{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# SplitRec：在隐语拆分学习中使用通信压缩\n",
    "\n",
    "> 注意： 以下代码仅供演示用途，在演示过程中可能会揭露部分信息。请勿直接将此示例代码用于实际生产环境中。在实际部署前，请根据您的具体需求和安全标准进行必要的修改和调整。\n",
    "\n",
    "> 本示例基于基于“拆分学习：银行营销”教程制作，建议先观看那个教程。\n",
    "\n",
    "在拆分学习中，由于模型被拆分在多个设备当中，进行训练的时候，各方需要对特征和梯度进行多次传输，带来很高的网络通讯消耗。为了减少通讯过程中的数据量，可以进行一些压缩处理。\n",
    "\n",
    "SecretFlow提供了Compressor对拆分学习中的数据进行压缩。同时也提供了多种基类，可以在此基础上实现自己的压缩算法。\n",
    "\n",
    "下面我们来试试一些算法的可用性，首先，我们在secretflow环境中创造2个实体alice和bob。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2023-08-16 01:43:59,294\tWARNING services.py:1732 -- WARNING: The object store is using /tmp instead of /dev/shm because /dev/shm has only 67108864 bytes available. This will harm performance! You may be able to free up space by deleting files in /dev/shm. If you are inside a Docker container, you can increase /dev/shm size by passing '--shm-size=3.92gb' to 'docker run' (or add it to the run_options list in a Ray cluster config). Make sure to set this to more than 30% of available RAM.\n",
      "2023-08-16 01:43:59,444\tINFO worker.py:1538 -- Started a local Ray instance.\n"
     ]
    }
   ],
   "source": [
    "import secretflow as sf\n",
    "\n",
    "sf.shutdown()\n",
    "sf.init(['alice', 'bob'], address='local')\n",
    "alice, bob = sf.PYU('alice'), sf.PYU('bob')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来我们准备要学习的数据。\n",
    "\n",
    "我们使用“拆分学习：银行营销”中的数据准备和处理方法，下载银行营销数据集并进行处理。alice和bob的角色和之前的教程完全相同："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\u001b[2m\u001b[36m(_run pid=27337)\u001b[0m /usr/local/lib/python3.8/site-packages/sklearn/base.py:443: UserWarning: X has feature names, but MinMaxScaler was fitted without feature names\n",
      "\u001b[2m\u001b[36m(_run pid=27337)\u001b[0m   warnings.warn(\n",
      "\u001b[2m\u001b[36m(_run pid=27337)\u001b[0m /usr/local/lib/python3.8/site-packages/sklearn/base.py:443: UserWarning: X has feature names, but MinMaxScaler was fitted without feature names\n",
      "\u001b[2m\u001b[36m(_run pid=27337)\u001b[0m   warnings.warn(\n"
     ]
    }
   ],
   "source": [
    "from secretflow.utils.simulation.datasets import load_bank_marketing\n",
    "from secretflow.preprocessing.scaler import MinMaxScaler\n",
    "from secretflow.preprocessing.encoder import LabelEncoder\n",
    "from secretflow.data.split import train_test_split\n",
    "\n",
    "random_state = 1234\n",
    "\n",
    "data = load_bank_marketing(parts={alice: (0, 4), bob: (4, 16)}, axis=1)\n",
    "label = load_bank_marketing(parts={alice: (16, 17)}, axis=1)\n",
    "\n",
    "encoder = LabelEncoder()\n",
    "data['job'] = encoder.fit_transform(data['job'])\n",
    "data['marital'] = encoder.fit_transform(data['marital'])\n",
    "data['education'] = encoder.fit_transform(data['education'])\n",
    "data['default'] = encoder.fit_transform(data['default'])\n",
    "data['housing'] = encoder.fit_transform(data['housing'])\n",
    "data['loan'] = encoder.fit_transform(data['loan'])\n",
    "data['contact'] = encoder.fit_transform(data['contact'])\n",
    "data['poutcome'] = encoder.fit_transform(data['poutcome'])\n",
    "data['month'] = encoder.fit_transform(data['month'])\n",
    "label = encoder.fit_transform(label)\n",
    "\n",
    "scaler = MinMaxScaler()\n",
    "data = scaler.fit_transform(data)\n",
    "\n",
    "train_data, test_data = train_test_split(\n",
    "    data, train_size=0.8, random_state=random_state\n",
    ")\n",
    "train_label, test_label = train_test_split(\n",
    "    label, train_size=0.8, random_state=random_state\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来我们创建联邦模型，同样地，我们使用“拆分学习：银行营销”中的建模，构建出base_model和fuse_model，然后就可以定义SLModel用于训练："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2023-08-16 01:44:03.512175: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n",
      "2023-08-16 01:44:04.209189: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory\n",
      "2023-08-16 01:44:04.209381: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory\n",
      "2023-08-16 01:44:04.209397: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n",
      "INFO:root:Create proxy actor <class 'secretflow_fl.ml.nn.sl.backend.tensorflow.sl_base.PYUSLTFModel'> with party alice.\n",
      "INFO:root:Create proxy actor <class 'secretflow_fl.ml.nn.sl.backend.tensorflow.sl_base.PYUSLTFModel'> with party bob.\n"
     ]
    }
   ],
   "source": [
    "def create_base_model(input_dim, output_dim, name='base_model'):\n",
    "    # Create model\n",
    "    def create_model():\n",
    "        from tensorflow import keras\n",
    "        from tensorflow.keras import layers\n",
    "        import tensorflow as tf\n",
    "\n",
    "        model = keras.Sequential(\n",
    "            [\n",
    "                keras.Input(shape=input_dim),\n",
    "                layers.Dense(100, activation=\"relu\"),\n",
    "                layers.Dense(output_dim, activation=\"relu\"),\n",
    "            ]\n",
    "        )\n",
    "        # Compile model\n",
    "        model.summary()\n",
    "        model.compile(\n",
    "            loss='binary_crossentropy',\n",
    "            optimizer='adam',\n",
    "            metrics=[\"accuracy\", tf.keras.metrics.AUC()],\n",
    "        )\n",
    "        return model\n",
    "\n",
    "    return create_model\n",
    "\n",
    "\n",
    "# prepare model\n",
    "hidden_size = 64\n",
    "\n",
    "model_base_alice = create_base_model(4, hidden_size)\n",
    "model_base_bob = create_base_model(12, hidden_size)\n",
    "\n",
    "\n",
    "def create_fuse_model(input_dim, output_dim, party_nums, name='fuse_model'):\n",
    "    def create_model():\n",
    "        from tensorflow import keras\n",
    "        from tensorflow.keras import layers\n",
    "        import tensorflow as tf\n",
    "\n",
    "        # input\n",
    "        input_layers = []\n",
    "        for i in range(party_nums):\n",
    "            input_layers.append(\n",
    "                keras.Input(\n",
    "                    input_dim,\n",
    "                )\n",
    "            )\n",
    "\n",
    "        merged_layer = layers.concatenate(input_layers)\n",
    "        fuse_layer = layers.Dense(64, activation='relu')(merged_layer)\n",
    "        output = layers.Dense(output_dim, activation='sigmoid')(fuse_layer)\n",
    "\n",
    "        model = keras.Model(inputs=input_layers, outputs=output)\n",
    "        model.summary()\n",
    "\n",
    "        model.compile(\n",
    "            loss='binary_crossentropy',\n",
    "            optimizer='adam',\n",
    "            metrics=[\"accuracy\", tf.keras.metrics.AUC()],\n",
    "        )\n",
    "        return model\n",
    "\n",
    "    return create_model\n",
    "\n",
    "\n",
    "model_fuse = create_fuse_model(input_dim=hidden_size, party_nums=2, output_dim=1)\n",
    "\n",
    "base_model_dict = {alice: model_base_alice, bob: model_base_bob}\n",
    "\n",
    "\n",
    "from secretflow_fl.ml.nn import SLModel\n",
    "\n",
    "sl_model_origin = SLModel(\n",
    "    base_model_dict=base_model_dict,\n",
    "    device_y=alice,\n",
    "    model_fuse=model_fuse,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 使用通讯压缩算法\n",
    "\n",
    "SecretFlow提供了Compressor，里面实现了各种基础的通讯压缩算法，可以直接使用。\n",
    "\n",
    "只要导入想使用的压缩算法并实例化,定义SLModel时将实例化的方法作为参数传入就可以在训练中实现通讯压缩。\n",
    "\n",
    "我们以QuantizedFP为例，该算法会将浮点数量化到8位以降低传输消耗。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:root:Create proxy actor <class 'secretflow_fl.ml.nn.sl.backend.tensorflow.sl_base.PYUSLTFModel'> with party alice.\n",
      "INFO:root:Create proxy actor <class 'secretflow_fl.ml.nn.sl.backend.tensorflow.sl_base.PYUSLTFModel'> with party bob.\n"
     ]
    }
   ],
   "source": [
    "from secretflow_fl.utils.compressor import QuantizedFP\n",
    "\n",
    "qfp = QuantizedFP()\n",
    "\n",
    "sl_model_compress = SLModel(\n",
    "    base_model_dict=base_model_dict,\n",
    "    device_y=alice,\n",
    "    model_fuse=model_fuse,\n",
    "    compressor=qfp,  # 在这里传入实例化的compressor算法\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们分别对没有使用通讯压缩的模型和使用了量化压缩的模型进行训练，并把训练轮次拉高到40轮，看看效果如何。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:root:SL Train Params: {'x': VDataFrame(partitions={PYURuntime(alice): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f37c4db5310>), PYURuntime(bob): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f37c4de31c0>)}, aligned=True), 'y': VDataFrame(partitions={PYURuntime(alice): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f37c4675a60>)}, aligned=True), 'batch_size': 128, 'epochs': 40, 'verbose': 1, 'callbacks': None, 'validation_data': (VDataFrame(partitions={PYURuntime(alice): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f3769f921f0>), PYURuntime(bob): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f37c4de3190>)}, aligned=True), VDataFrame(partitions={PYURuntime(alice): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f37c4675dc0>)}, aligned=True)), 'shuffle': True, 'sample_weight': None, 'validation_freq': 1, 'dp_spent_step_freq': None, 'dataset_builder': None, 'audit_log_params': {}, 'random_seed': 11819, 'audit_log_dir': None, 'self': <secretflow_fl.ml.nn.sl.sl_model.SLModel object at 0x7f37ec6ec6d0>}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\u001b[2m\u001b[36m(pid=28114)\u001b[0m 2023-08-16 01:44:08.296739: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=28127)\u001b[0m 2023-08-16 01:44:08.551930: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=28181)\u001b[0m 2023-08-16 01:44:08.767248: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=28235)\u001b[0m 2023-08-16 01:44:09.014466: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=28114)\u001b[0m 2023-08-16 01:44:09.160525: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=28114)\u001b[0m 2023-08-16 01:44:09.160694: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=28114)\u001b[0m 2023-08-16 01:44:09.160713: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n",
      "\u001b[2m\u001b[36m(pid=28127)\u001b[0m 2023-08-16 01:44:09.418021: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=28127)\u001b[0m 2023-08-16 01:44:09.418136: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=28127)\u001b[0m 2023-08-16 01:44:09.418152: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n",
      "\u001b[2m\u001b[36m(pid=28181)\u001b[0m 2023-08-16 01:44:09.654066: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=28181)\u001b[0m 2023-08-16 01:44:09.654235: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=28181)\u001b[0m 2023-08-16 01:44:09.654257: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n",
      "\u001b[2m\u001b[36m(pid=28235)\u001b[0m 2023-08-16 01:44:09.871219: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=28235)\u001b[0m 2023-08-16 01:44:09.871317: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=28235)\u001b[0m 2023-08-16 01:44:09.871333: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m 2023-08-16 01:44:11.224977: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m 2023-08-16 01:44:11.225041: W tensorflow/compiler/xla/stream_executor/cuda/cuda_driver.cc:265] failed call to cuInit: UNKNOWN ERROR (303)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m Model: \"sequential\"\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m _________________________________________________________________\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m  Layer (type)                Output Shape              Param #   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m =================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m  dense (Dense)               (None, 100)               500       \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m                                                                  \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m  dense_1 (Dense)             (None, 64)                6464      \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m                                                                  \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m =================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m Total params: 6,964\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m Trainable params: 6,964\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m Non-trainable params: 0\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m _________________________________________________________________\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m Model: \"model\"\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m __________________________________________________________________________________________________\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m  Layer (type)                   Output Shape         Param #     Connected to                     \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m ==================================================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m  input_2 (InputLayer)           [(None, 64)]         0           []                               \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m                                                                                                   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m  input_3 (InputLayer)           [(None, 64)]         0           []                               \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m                                                                                                   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m  concatenate (Concatenate)      (None, 128)          0           ['input_2[0][0]',                \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m                                                                   'input_3[0][0]']                \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m                                                                                                   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m  dense_2 (Dense)                (None, 64)           8256        ['concatenate[0][0]']            \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m                                                                                                   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m  dense_3 (Dense)                (None, 1)            65          ['dense_2[0][0]']                \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m                                                                                                   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m ==================================================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m Total params: 8,321\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m Trainable params: 8,321\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m Non-trainable params: 0\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28114)\u001b[0m __________________________________________________________________________________________________\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28127)\u001b[0m 2023-08-16 01:44:11.487105: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28127)\u001b[0m 2023-08-16 01:44:11.487150: W tensorflow/compiler/xla/stream_executor/cuda/cuda_driver.cc:265] failed call to cuInit: UNKNOWN ERROR (303)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28127)\u001b[0m Model: \"sequential\"\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28127)\u001b[0m _________________________________________________________________\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28127)\u001b[0m  Layer (type)                Output Shape              Param #   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28127)\u001b[0m =================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28127)\u001b[0m  dense (Dense)               (None, 100)               1300      \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28127)\u001b[0m                                                                  \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28127)\u001b[0m  dense_1 (Dense)             (None, 64)                6464      \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28127)\u001b[0m                                                                  \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28127)\u001b[0m =================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28127)\u001b[0m Total params: 7,764\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28127)\u001b[0m Trainable params: 7,764\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28127)\u001b[0m Non-trainable params: 0\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28127)\u001b[0m _________________________________________________________________\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "  0%|          | 0/29 [00:00<?, ?it/s]\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m 2023-08-16 01:44:11.750458: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m 2023-08-16 01:44:11.750499: W tensorflow/compiler/xla/stream_executor/cuda/cuda_driver.cc:265] failed call to cuInit: UNKNOWN ERROR (303)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m Model: \"sequential\"\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m _________________________________________________________________\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m  Layer (type)                Output Shape              Param #   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m =================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m  dense (Dense)               (None, 100)               500       \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m                                                                  \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m  dense_1 (Dense)             (None, 64)                6464      \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m                                                                  \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m =================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m Total params: 6,964\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m Trainable params: 6,964\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m Non-trainable params: 0\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m _________________________________________________________________\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m Model: \"model\"\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m __________________________________________________________________________________________________\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m  Layer (type)                   Output Shape         Param #     Connected to                     \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m ==================================================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m  input_2 (InputLayer)           [(None, 64)]         0           []                               \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m                                                                                                   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m  input_3 (InputLayer)           [(None, 64)]         0           []                               \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m                                                                                                   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m  concatenate (Concatenate)      (None, 128)          0           ['input_2[0][0]',                \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m                                                                   'input_3[0][0]']                \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m                                                                                                   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m  dense_2 (Dense)                (None, 64)           8256        ['concatenate[0][0]']            \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m                                                                                                   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m  dense_3 (Dense)                (None, 1)            65          ['dense_2[0][0]']                \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m                                                                                                   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m ==================================================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m Total params: 8,321\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m Trainable params: 8,321\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m Non-trainable params: 0\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28181)\u001b[0m __________________________________________________________________________________________________\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28235)\u001b[0m 2023-08-16 01:44:11.944846: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28235)\u001b[0m 2023-08-16 01:44:11.944886: W tensorflow/compiler/xla/stream_executor/cuda/cuda_driver.cc:265] failed call to cuInit: UNKNOWN ERROR (303)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28235)\u001b[0m Model: \"sequential\"\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28235)\u001b[0m _________________________________________________________________\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28235)\u001b[0m  Layer (type)                Output Shape              Param #   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28235)\u001b[0m =================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28235)\u001b[0m  dense (Dense)               (None, 100)               1300      \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28235)\u001b[0m                                                                  \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28235)\u001b[0m  dense_1 (Dense)             (None, 64)                6464      \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28235)\u001b[0m                                                                  \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28235)\u001b[0m =================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28235)\u001b[0m Total params: 7,764\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28235)\u001b[0m Trainable params: 7,764\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28235)\u001b[0m Non-trainable params: 0\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=28235)\u001b[0m _________________________________________________________________\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2023-08-16 01:44:12.766822: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory\n",
      "2023-08-16 01:44:12.766872: W tensorflow/compiler/xla/stream_executor/cuda/cuda_driver.cc:265] failed call to cuInit: UNKNOWN ERROR (303)\n",
      "  7%|▋         | 2/29 [00:01<00:15,  1.71it/s]\u001b[2m\u001b[36m(_run pid=27349)\u001b[0m 2023-08-16 01:44:13.072502: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(_run pid=27349)\u001b[0m 2023-08-16 01:44:13.779506: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(_run pid=27349)\u001b[0m 2023-08-16 01:44:13.779666: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(_run pid=27349)\u001b[0m 2023-08-16 01:44:13.779683: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n",
      "\u001b[2m\u001b[36m(_run pid=27349)\u001b[0m 2023-08-16 01:44:15.482702: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(_run pid=27349)\u001b[0m 2023-08-16 01:44:15.482741: W tensorflow/compiler/xla/stream_executor/cuda/cuda_driver.cc:265] failed call to cuInit: UNKNOWN ERROR (303)\n",
      "100%|██████████| 29/29 [00:05<00:00,  4.90it/s, epoch: 1/40 -  train_loss:0.4123900532722473  train_accuracy:0.8816371560096741  train_auc_1:0.5304562449455261  val_loss:0.3779788911342621  val_accuracy:0.8729282021522522  val_auc_1:0.6028343439102173 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.61it/s, epoch: 2/40 -  train_loss:0.346932053565979  train_accuracy:0.8819137215614319  train_auc_1:0.6658823490142822  val_loss:0.36548909544944763  val_accuracy:0.8729282021522522  val_auc_1:0.6796367764472961 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.64it/s, epoch: 3/40 -  train_loss:0.3372674584388733  train_accuracy:0.8816371560096741  train_auc_1:0.7067811489105225  val_loss:0.35295170545578003  val_accuracy:0.8729282021522522  val_auc_1:0.7270445823669434 ]\n",
      " 90%|████████▉ | 26/29 [00:00<00:00, 29.28it/s]\u001b[2m\u001b[36m(_run pid=27337)\u001b[0m 2023-08-16 01:44:20.568055: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(_run pid=27337)\u001b[0m 2023-08-16 01:44:21.249659: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(_run pid=27337)\u001b[0m 2023-08-16 01:44:21.249744: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(_run pid=27337)\u001b[0m 2023-08-16 01:44:21.249758: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n",
      "\u001b[2m\u001b[36m(_run pid=27337)\u001b[0m 2023-08-16 01:44:22.997208: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(_run pid=27337)\u001b[0m 2023-08-16 01:44:22.997268: W tensorflow/compiler/xla/stream_executor/cuda/cuda_driver.cc:265] failed call to cuInit: UNKNOWN ERROR (303)\n",
      "100%|██████████| 29/29 [00:03<00:00,  7.81it/s, epoch: 4/40 -  train_loss:0.32340219616889954  train_accuracy:0.8769886493682861  train_auc_1:0.7885534763336182  val_loss:0.33063772320747375  val_accuracy:0.8729282021522522  val_auc_1:0.7887451648712158 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 30.04it/s, epoch: 5/40 -  train_loss:0.26995792984962463  train_accuracy:0.8907632827758789  train_auc_1:0.838128924369812  val_loss:0.3076745867729187  val_accuracy:0.870718240737915  val_auc_1:0.8215299844741821 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.33it/s, epoch: 6/40 -  train_loss:0.2533552348613739  train_accuracy:0.8924225568771362  train_auc_1:0.8705887794494629  val_loss:0.29530927538871765  val_accuracy:0.8773480653762817  val_auc_1:0.8317886590957642 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 30.32it/s, epoch: 7/40 -  train_loss:0.24668139219284058  train_accuracy:0.8990597128868103  train_auc_1:0.8558321595191956  val_loss:0.28804725408554077  val_accuracy:0.8839778900146484  val_auc_1:0.8480352163314819 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.50it/s, epoch: 8/40 -  train_loss:0.23031719028949738  train_accuracy:0.9137167930603027  train_auc_1:0.8611728549003601  val_loss:0.3139592111110687  val_accuracy:0.8762431144714355  val_auc_1:0.846015453338623 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 30.08it/s, epoch: 9/40 -  train_loss:0.23515202105045319  train_accuracy:0.900053858757019  train_auc_1:0.8805654048919678  val_loss:0.28104230761528015  val_accuracy:0.8795580267906189  val_auc_1:0.8522399663925171 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 26.20it/s, epoch: 10/40 -  train_loss:0.241227924823761  train_accuracy:0.9048295617103577  train_auc_1:0.8812973499298096  val_loss:0.2837042808532715  val_accuracy:0.8762431144714355  val_auc_1:0.8458613157272339 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.39it/s, epoch: 11/40 -  train_loss:0.24319183826446533  train_accuracy:0.8978987336158752  train_auc_1:0.8969712257385254  val_loss:0.2814089357852936  val_accuracy:0.8806629776954651  val_auc_1:0.8504238128662109 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.38it/s, epoch: 12/40 -  train_loss:0.23649084568023682  train_accuracy:0.9022090435028076  train_auc_1:0.8886930346488953  val_loss:0.2808994650840759  val_accuracy:0.8806629776954651  val_auc_1:0.8507044315338135 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.70it/s, epoch: 13/40 -  train_loss:0.2257165014743805  train_accuracy:0.912446141242981  train_auc_1:0.8892974853515625  val_loss:0.2844206690788269  val_accuracy:0.8817679286003113  val_auc_1:0.8516015410423279 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.98it/s, epoch: 14/40 -  train_loss:0.2239973098039627  train_accuracy:0.9110991358757019  train_auc_1:0.8925117254257202  val_loss:0.27834010124206543  val_accuracy:0.8828729391098022  val_auc_1:0.8576555252075195 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 30.14it/s, epoch: 15/40 -  train_loss:0.22855830192565918  train_accuracy:0.9065265655517578  train_auc_1:0.9059909582138062  val_loss:0.27655595541000366  val_accuracy:0.8828729391098022  val_auc_1:0.8548376560211182 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.99it/s, epoch: 16/40 -  train_loss:0.23442411422729492  train_accuracy:0.8992456793785095  train_auc_1:0.8952087759971619  val_loss:0.29822733998298645  val_accuracy:0.8773480653762817  val_auc_1:0.8496862649917603 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 30.22it/s, epoch: 17/40 -  train_loss:0.22274373471736908  train_accuracy:0.9148706793785095  train_auc_1:0.8883383870124817  val_loss:0.2906903922557831  val_accuracy:0.8795580267906189  val_auc_1:0.8574408292770386 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 30.02it/s, epoch: 18/40 -  train_loss:0.23235483467578888  train_accuracy:0.908462405204773  train_auc_1:0.8890659809112549  val_loss:0.2833332121372223  val_accuracy:0.8784530162811279  val_auc_1:0.853417694568634 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 30.11it/s, epoch: 19/40 -  train_loss:0.21570773422718048  train_accuracy:0.9125000238418579  train_auc_1:0.9087664484977722  val_loss:0.28136932849884033  val_accuracy:0.8773480653762817  val_auc_1:0.852614164352417 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 30.17it/s, epoch: 20/40 -  train_loss:0.22992058098316193  train_accuracy:0.9043141603469849  train_auc_1:0.9015873670578003  val_loss:0.2777860164642334  val_accuracy:0.8861878514289856  val_auc_1:0.8568739891052246 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.56it/s, epoch: 21/40 -  train_loss:0.2279340922832489  train_accuracy:0.9051437973976135  train_auc_1:0.8971817493438721  val_loss:0.2807583212852478  val_accuracy:0.8751381039619446  val_auc_1:0.8563731908798218 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 30.77it/s, epoch: 22/40 -  train_loss:0.21565255522727966  train_accuracy:0.9123831987380981  train_auc_1:0.9007200002670288  val_loss:0.2829255759716034  val_accuracy:0.8861878514289856  val_auc_1:0.8530654907226562 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 28.86it/s, epoch: 23/40 -  train_loss:0.2037818878889084  train_accuracy:0.9172952771186829  train_auc_1:0.9117729067802429  val_loss:0.283769816160202  val_accuracy:0.8806629776954651  val_auc_1:0.8584370613098145 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.94it/s, epoch: 24/40 -  train_loss:0.20522674918174744  train_accuracy:0.9189712405204773  train_auc_1:0.9200270175933838  val_loss:0.2849152088165283  val_accuracy:0.8872928023338318  val_auc_1:0.8554760217666626 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.87it/s, epoch: 25/40 -  train_loss:0.21887396275997162  train_accuracy:0.9092133641242981  train_auc_1:0.8964812755584717  val_loss:0.28434526920318604  val_accuracy:0.8817679286003113  val_auc_1:0.8562740087509155 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 30.06it/s, epoch: 26/40 -  train_loss:0.21427837014198303  train_accuracy:0.9110991358757019  train_auc_1:0.9081460237503052  val_loss:0.2802579998970032  val_accuracy:0.8806629776954651  val_auc_1:0.8563676476478577 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.95it/s, epoch: 27/40 -  train_loss:0.21740949153900146  train_accuracy:0.9131637215614319  train_auc_1:0.900717556476593  val_loss:0.288614422082901  val_accuracy:0.8795580267906189  val_auc_1:0.8571600914001465 ]\n",
      " 90%|████████▉ | 26/29 [00:00<00:00, 30.69it/s]\u001b[2m\u001b[36m(_run pid=27350)\u001b[0m 2023-08-16 01:44:46.829048: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(_run pid=27350)\u001b[0m 2023-08-16 01:44:47.528208: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(_run pid=27350)\u001b[0m 2023-08-16 01:44:47.528303: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(_run pid=27350)\u001b[0m 2023-08-16 01:44:47.528317: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n",
      "\u001b[2m\u001b[36m(_run pid=27350)\u001b[0m 2023-08-16 01:44:49.224472: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(_run pid=27350)\u001b[0m 2023-08-16 01:44:49.224513: W tensorflow/compiler/xla/stream_executor/cuda/cuda_driver.cc:265] failed call to cuInit: UNKNOWN ERROR (303)\n",
      "100%|██████████| 29/29 [00:03<00:00,  7.90it/s, epoch: 28/40 -  train_loss:0.20581252872943878  train_accuracy:0.9156526327133179  train_auc_1:0.9221852421760559  val_loss:0.2895594835281372  val_accuracy:0.8861878514289856  val_auc_1:0.853269100189209 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.86it/s, epoch: 29/40 -  train_loss:0.21550066769123077  train_accuracy:0.9065265655517578  train_auc_1:0.9204001426696777  val_loss:0.2893003225326538  val_accuracy:0.8773480653762817  val_auc_1:0.8543698191642761 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 30.12it/s, epoch: 30/40 -  train_loss:0.2129545956850052  train_accuracy:0.9103982448577881  train_auc_1:0.9062888622283936  val_loss:0.2805260717868805  val_accuracy:0.8861878514289856  val_auc_1:0.857974648475647 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 30.07it/s, epoch: 31/40 -  train_loss:0.21476531028747559  train_accuracy:0.9113636612892151  train_auc_1:0.9071635007858276  val_loss:0.28486552834510803  val_accuracy:0.8861878514289856  val_auc_1:0.8532305955886841 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 30.47it/s, epoch: 32/40 -  train_loss:0.21274054050445557  train_accuracy:0.9136363863945007  train_auc_1:0.9150363802909851  val_loss:0.28660014271736145  val_accuracy:0.8828729391098022  val_auc_1:0.8550137877464294 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.68it/s, epoch: 33/40 -  train_loss:0.19922088086605072  train_accuracy:0.9162057638168335  train_auc_1:0.925368070602417  val_loss:0.28454411029815674  val_accuracy:0.8839778900146484  val_auc_1:0.8589598536491394 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 28.91it/s, epoch: 34/40 -  train_loss:0.19305925071239471  train_accuracy:0.9264547228813171  train_auc_1:0.9245292544364929  val_loss:0.2927177846431732  val_accuracy:0.8850829005241394  val_auc_1:0.8632690906524658 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.83it/s, epoch: 35/40 -  train_loss:0.18927669525146484  train_accuracy:0.9245793223381042  train_auc_1:0.9269171953201294  val_loss:0.28897616267204285  val_accuracy:0.8839778900146484  val_auc_1:0.8587452173233032 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 28.43it/s, epoch: 36/40 -  train_loss:0.20300477743148804  train_accuracy:0.917640209197998  train_auc_1:0.921332836151123  val_loss:0.2856888175010681  val_accuracy:0.8817679286003113  val_auc_1:0.8576774597167969 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 28.36it/s, epoch: 37/40 -  train_loss:0.21484363079071045  train_accuracy:0.9117809534072876  train_auc_1:0.9073271155357361  val_loss:0.28348052501678467  val_accuracy:0.8795580267906189  val_auc_1:0.8578591346740723 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.46it/s, epoch: 38/40 -  train_loss:0.2097211331129074  train_accuracy:0.9109513163566589  train_auc_1:0.9167930483818054  val_loss:0.28846046328544617  val_accuracy:0.8828729391098022  val_auc_1:0.8501706123352051 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 30.17it/s, epoch: 39/40 -  train_loss:0.211452916264534  train_accuracy:0.9207974076271057  train_auc_1:0.9071869254112244  val_loss:0.2857007682323456  val_accuracy:0.8850829005241394  val_auc_1:0.8534011840820312 ]\n",
      "100%|██████████| 29/29 [00:00<00:00, 29.72it/s, epoch: 40/40 -  train_loss:0.1950661838054657  train_accuracy:0.9189712405204773  train_auc_1:0.9238503575325012  val_loss:0.287675678730011  val_accuracy:0.8839778900146484  val_auc_1:0.8539405465126038 ]\n",
      "INFO:root:SL Train Params: {'x': VDataFrame(partitions={PYURuntime(alice): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f37c4db5310>), PYURuntime(bob): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f37c4de31c0>)}, aligned=True), 'y': VDataFrame(partitions={PYURuntime(alice): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f37c4675a60>)}, aligned=True), 'batch_size': 128, 'epochs': 40, 'verbose': 1, 'callbacks': None, 'validation_data': (VDataFrame(partitions={PYURuntime(alice): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f3769f921f0>), PYURuntime(bob): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f37c4de3190>)}, aligned=True), VDataFrame(partitions={PYURuntime(alice): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f37c4675dc0>)}, aligned=True)), 'shuffle': True, 'sample_weight': None, 'validation_freq': 1, 'dp_spent_step_freq': None, 'dataset_builder': None, 'audit_log_params': {}, 'random_seed': 50480, 'audit_log_dir': None, 'self': <secretflow_fl.ml.nn.sl.sl_model.SLModel object at 0x7f37c4624cd0>}\n",
      "100%|██████████| 29/29 [00:03<00:00,  7.41it/s, epoch: 1/40 -  train_loss:0.4217776954174042  train_accuracy:0.8659462332725525  train_auc_1:0.5435447692871094  val_loss:0.40626364946365356  val_accuracy:0.8729282021522522  val_auc_1:0.5905393362045288 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.59it/s, epoch: 2/40 -  train_loss:0.3423333764076233  train_accuracy:0.8874446749687195  train_auc_1:0.6285374164581299  val_loss:0.3637339770793915  val_accuracy:0.8729282021522522  val_auc_1:0.670577883720398 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 16.02it/s, epoch: 3/40 -  train_loss:0.31453219056129456  train_accuracy:0.8949353694915771  train_auc_1:0.6967648267745972  val_loss:0.35318124294281006  val_accuracy:0.8729282021522522  val_auc_1:0.7181453108787537 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.70it/s, epoch: 4/40 -  train_loss:0.2924026548862457  train_accuracy:0.8968473672866821  train_auc_1:0.771354079246521  val_loss:0.3476685583591461  val_accuracy:0.8729282021522522  val_auc_1:0.7567088603973389 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.96it/s, epoch: 5/40 -  train_loss:0.3236430585384369  train_accuracy:0.8690732717514038  train_auc_1:0.8049758076667786  val_loss:0.32425957918167114  val_accuracy:0.8729282021522522  val_auc_1:0.8028783798217773 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.77it/s, epoch: 6/40 -  train_loss:0.2683410346508026  train_accuracy:0.8920454382896423  train_auc_1:0.8347899317741394  val_loss:0.3059132695198059  val_accuracy:0.8696132302284241  val_auc_1:0.8184260129928589 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.99it/s, epoch: 7/40 -  train_loss:0.24226166307926178  train_accuracy:0.9022727012634277  train_auc_1:0.850990891456604  val_loss:0.30843329429626465  val_accuracy:0.8729282021522522  val_auc_1:0.832201361656189 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.66it/s, epoch: 8/40 -  train_loss:0.23420202732086182  train_accuracy:0.9053977131843567  train_auc_1:0.8667846322059631  val_loss:0.2918694317340851  val_accuracy:0.8795580267906189  val_auc_1:0.8382883071899414 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.87it/s, epoch: 9/40 -  train_loss:0.24281850457191467  train_accuracy:0.8993362784385681  train_auc_1:0.8600778579711914  val_loss:0.28592929244041443  val_accuracy:0.8773480653762817  val_auc_1:0.8522564172744751 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 16.07it/s, epoch: 10/40 -  train_loss:0.25411662459373474  train_accuracy:0.8985795378684998  train_auc_1:0.8763052225112915  val_loss:0.27862876653671265  val_accuracy:0.8795580267906189  val_auc_1:0.8518161773681641 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.97it/s, epoch: 11/40 -  train_loss:0.2467927783727646  train_accuracy:0.9008620977401733  train_auc_1:0.8637750148773193  val_loss:0.27538853883743286  val_accuracy:0.8850829005241394  val_auc_1:0.8585635423660278 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.81it/s, epoch: 12/40 -  train_loss:0.24046260118484497  train_accuracy:0.9030172228813171  train_auc_1:0.8943703174591064  val_loss:0.2793208956718445  val_accuracy:0.8872928023338318  val_auc_1:0.8582884073257446 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.74it/s, epoch: 13/40 -  train_loss:0.2232421338558197  train_accuracy:0.9109513163566589  train_auc_1:0.9031308889389038  val_loss:0.27965837717056274  val_accuracy:0.8773480653762817  val_auc_1:0.857512354850769 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.98it/s, epoch: 14/40 -  train_loss:0.2226562350988388  train_accuracy:0.9120911359786987  train_auc_1:0.8835855722427368  val_loss:0.28520363569259644  val_accuracy:0.8806629776954651  val_auc_1:0.854595422744751 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.90it/s, epoch: 15/40 -  train_loss:0.23515889048576355  train_accuracy:0.904902994632721  train_auc_1:0.8961691856384277  val_loss:0.28021782636642456  val_accuracy:0.8850829005241394  val_auc_1:0.8563291430473328 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.79it/s, epoch: 16/40 -  train_loss:0.23402053117752075  train_accuracy:0.9024784564971924  train_auc_1:0.8906980752944946  val_loss:0.27909329533576965  val_accuracy:0.8850829005241394  val_auc_1:0.859708309173584 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.93it/s, epoch: 17/40 -  train_loss:0.2111150622367859  train_accuracy:0.9189712405204773  train_auc_1:0.8960785865783691  val_loss:0.27899590134620667  val_accuracy:0.8817679286003113  val_auc_1:0.8576114177703857 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.81it/s, epoch: 18/40 -  train_loss:0.20241659879684448  train_accuracy:0.915678858757019  train_auc_1:0.9157640933990479  val_loss:0.28282174468040466  val_accuracy:0.8784530162811279  val_auc_1:0.8583985567092896 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.87it/s, epoch: 19/40 -  train_loss:0.23259153962135315  train_accuracy:0.9071022868156433  train_auc_1:0.8956990242004395  val_loss:0.2828892171382904  val_accuracy:0.8817679286003113  val_auc_1:0.8546835780143738 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.82it/s, epoch: 20/40 -  train_loss:0.22440506517887115  train_accuracy:0.9034845232963562  train_auc_1:0.8989371657371521  val_loss:0.28058287501335144  val_accuracy:0.8784530162811279  val_auc_1:0.8598239421844482 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.94it/s, epoch: 21/40 -  train_loss:0.23205137252807617  train_accuracy:0.9051724076271057  train_auc_1:0.8899630308151245  val_loss:0.2741439938545227  val_accuracy:0.8795580267906189  val_auc_1:0.8636598587036133 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.72it/s, epoch: 22/40 -  train_loss:0.22656284272670746  train_accuracy:0.9030172228813171  train_auc_1:0.907919704914093  val_loss:0.2767719030380249  val_accuracy:0.8839778900146484  val_auc_1:0.8592514991760254 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.98it/s, epoch: 23/40 -  train_loss:0.22055070102214813  train_accuracy:0.9109228849411011  train_auc_1:0.913796067237854  val_loss:0.2815714180469513  val_accuracy:0.8928176760673523  val_auc_1:0.855701744556427 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.60it/s, epoch: 24/40 -  train_loss:0.23475250601768494  train_accuracy:0.9043141603469849  train_auc_1:0.9076265692710876  val_loss:0.2773815095424652  val_accuracy:0.8839778900146484  val_auc_1:0.8560759425163269 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 16.07it/s, epoch: 25/40 -  train_loss:0.2359710931777954  train_accuracy:0.9005681872367859  train_auc_1:0.9041743278503418  val_loss:0.28951746225357056  val_accuracy:0.8806629776954651  val_auc_1:0.8590589165687561 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.76it/s, epoch: 26/40 -  train_loss:0.21646590530872345  train_accuracy:0.9094827771186829  train_auc_1:0.9059643745422363  val_loss:0.27530720829963684  val_accuracy:0.8806629776954651  val_auc_1:0.8600990772247314 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.82it/s, epoch: 27/40 -  train_loss:0.21936063468456268  train_accuracy:0.9137930870056152  train_auc_1:0.9077043533325195  val_loss:0.2782182991504669  val_accuracy:0.8861878514289856  val_auc_1:0.8611392974853516 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 16.03it/s, epoch: 28/40 -  train_loss:0.21766482293605804  train_accuracy:0.9098451137542725  train_auc_1:0.9155865907669067  val_loss:0.2878170311450958  val_accuracy:0.8806629776954651  val_auc_1:0.8582608103752136 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.72it/s, epoch: 29/40 -  train_loss:0.2088153064250946  train_accuracy:0.9126105904579163  train_auc_1:0.9115303754806519  val_loss:0.28278136253356934  val_accuracy:0.8817679286003113  val_auc_1:0.8566923141479492 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.74it/s, epoch: 30/40 -  train_loss:0.2089204490184784  train_accuracy:0.9156526327133179  train_auc_1:0.9117385149002075  val_loss:0.2774920165538788  val_accuracy:0.8861878514289856  val_auc_1:0.8575839996337891 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.52it/s, epoch: 31/40 -  train_loss:0.20840761065483093  train_accuracy:0.9170354008674622  train_auc_1:0.909948468208313  val_loss:0.29270535707473755  val_accuracy:0.8817679286003113  val_auc_1:0.8584149479866028 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.67it/s, epoch: 32/40 -  train_loss:0.21289651095867157  train_accuracy:0.9139933586120605  train_auc_1:0.9137017130851746  val_loss:0.2861045300960541  val_accuracy:0.8872928023338318  val_auc_1:0.8621078729629517 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 16.06it/s, epoch: 33/40 -  train_loss:0.20959915220737457  train_accuracy:0.9116379022598267  train_auc_1:0.9085273146629333  val_loss:0.2869407832622528  val_accuracy:0.8828729391098022  val_auc_1:0.8602972030639648 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.91it/s, epoch: 34/40 -  train_loss:0.20927441120147705  train_accuracy:0.91731196641922  train_auc_1:0.9242825508117676  val_loss:0.2853357195854187  val_accuracy:0.8872928023338318  val_auc_1:0.8595817685127258 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.88it/s, epoch: 35/40 -  train_loss:0.21317821741104126  train_accuracy:0.9164719581604004  train_auc_1:0.9171379208564758  val_loss:0.2900511920452118  val_accuracy:0.8795580267906189  val_auc_1:0.8606053590774536 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.76it/s, epoch: 36/40 -  train_loss:0.22284917533397675  train_accuracy:0.909375011920929  train_auc_1:0.903253436088562  val_loss:0.2755865752696991  val_accuracy:0.8839778900146484  val_auc_1:0.8629168272018433 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.70it/s, epoch: 37/40 -  train_loss:0.19849534332752228  train_accuracy:0.9175646305084229  train_auc_1:0.923616886138916  val_loss:0.289157897233963  val_accuracy:0.8784530162811279  val_auc_1:0.8603851795196533 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.88it/s, epoch: 38/40 -  train_loss:0.20322787761688232  train_accuracy:0.9178650379180908  train_auc_1:0.9194050431251526  val_loss:0.2820649743080139  val_accuracy:0.8850829005241394  val_auc_1:0.8655640482902527 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.71it/s, epoch: 39/40 -  train_loss:0.1862594485282898  train_accuracy:0.9291487336158752  train_auc_1:0.9243948459625244  val_loss:0.2956363558769226  val_accuracy:0.8872928023338318  val_auc_1:0.8605613708496094 ]\n",
      "100%|██████████| 29/29 [00:01<00:00, 15.88it/s, epoch: 40/40 -  train_loss:0.20305216312408447  train_accuracy:0.915409505367279  train_auc_1:0.912611722946167  val_loss:0.2843382656574249  val_accuracy:0.8806629776954651  val_auc_1:0.8598018288612366 ]\n"
     ]
    }
   ],
   "source": [
    "histories = []\n",
    "for sl_model in [sl_model_origin, sl_model_compress]:\n",
    "    history = sl_model.fit(\n",
    "        train_data,\n",
    "        train_label,\n",
    "        validation_data=(test_data, test_label),\n",
    "        epochs=40,\n",
    "        batch_size=128,\n",
    "        shuffle=True,\n",
    "        verbose=1,\n",
    "        validation_freq=1,\n",
    "    )\n",
    "\n",
    "    histories.append(history)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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/v2xWq3MmDGjyPZPPvkEjUZjH0l24f7yUWTTp08v8lyn0zF06FCWLFnCoUOHir1eUlKSw9cyf/58unbtyvDhw7nnnnuK3F544QUAfvrppyuW4UhcF5Is5ZJpALZv387WrVvLFG///v2JjY1l2bJlRbabTCa+++47AgICaNWqVZnKurxci8XCV199Zd9mtVr5/PPPixwXEBBAjx49+Prrrzl//nyxcsrzO7jgnnvuISIignfeeafEn0dWVhYvv/yy/Xm9evXYtm0bBQUF9m2///47MTExDr1uo0aNiIiIYNGiRSxatIjq1avTrVs3+/7KeN8JURGkBkiIKlBaU8ClBgwYQM+ePXn55Zc5c+YMzZs35++//2b58uU888wz9j4/LVq0YOTIkXz55ZdkZGTQqVMn1q5dS2RkZLEy33vvPdatW0f79u2ZMGECjRs3JjU1lT179rBmzRpSU1PLfA3bt28nMjKSiRMnlrg/ODiYVq1aMX/+fP7v//7vimWVNa677rqLpUuXMmTIEO68805Onz7NzJkzady4MdnZ2VeN+eGHH2b27NkMGzaMBx54gJYtW5KSksKiRYs4dOgQc+fOtXeydsSAAQPo3LkzL730EmfOnKFx48YsXbqUjIyMYsd+8cUXdOnShYiICCZMmEDdunVJSEhg69atxMbGsn//fodfH9RapaVLl9K7d2+6devGvffeS+fOnTEYDBw+fJgFCxbg4+NjnwvooYceYvHixfTr1497772XqKgo5s2bV6wvWVkMHz6cV199FWdnZx588EG02qLfrSvyfSdEhamy8WdC3CIuHQZ/JSUN0c7KylKeffZZpUaNGorBYFDCwsKUDz/8ULHZbEWOy8vLU5566inF19dXcXNzUwYMGKDExMQUGwavKOqw9SeeeEIJCQlRDAaDEhQUpNx2223KN998Yz+mLMPgn3zySQVQoqKiSj3m9ddfVwBl//79iqKow+CfeOKJEo8tS1w2m0159913ldq1aytOTk5Ky5Ytld9//10ZO3asUrt27VLjuFRaWpry7LPPKnXq1FEMBoPi6emp9OzZU1m5cmWxY8eOHau4ubkV2/7aa68pl//7TElJUUaPHq14enoqXl5eyujRo5W9e/eW+HOMiopSxowZowQFBSkGg0EJDg5W7rrrLmXx4sX2Y8r6vinp+l599VUlIiJCcXV1VZyd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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "for history in histories:\n",
    "    plt.plot(history['train_auc_1'])\n",
    "    plt.plot(history['val_auc_1'])\n",
    "\n",
    "plt.title('Model Area Under Curve')\n",
    "plt.ylabel('Area Under Curve')\n",
    "plt.xlabel('Epoch')\n",
    "plt.legend(\n",
    "    ['origin', 'origin_val', 'fp8_compressed', 'fp8_compressed_val'], loc='lower right'\n",
    ")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到，两个模型的验证集auc均在0.85左右波动，使用8位量化对此任务的训练精度影响不大，而理论通讯消耗减少了3/4（从32位减少到了8位）。\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 自定义通讯压缩算法\n",
    "\n",
    "我们也可以自定义一个压缩算法，SecretFlow提供了SparseCompressor和QuantizedCompressor基类，对应稀疏化方法和量化压缩方法。\n",
    "\n",
    "这里以量化压缩方法为例，来实现一个基于K-means的压缩算法。\n",
    "\n",
    "K-means压缩论文是\"Deep Compression: Compressing Deep Neural Networks with Pruning, Trained Quantization and Huffman Coding\"提出的方法中的其中一个步骤，其思想是把对传输参数进行聚类，保存聚类中心的值，然后把其他值用聚类序号来表示。\n",
    "\n",
    "继承QuantizedCompressor后，只要实现_compress_one（将一个numpy向量打包为QuantizedCompressedData） 和 _decompress_one（将QuantizedCompressedData还原回numpy向量）函数即可。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "from secretflow_fl.utils.compressor import QuantizedCompressor\n",
    "from secretflow_fl.utils.compressor.quantized_compressor import QuantizedCompressedData\n",
    "import numpy as np\n",
    "\n",
    "\n",
    "class QuantizedKmeans(QuantizedCompressor):\n",
    "    \"\"\"Quantized compressor with Kmeans, a algorithm which replace float with relatived centroid's index.\n",
    "\n",
    "    Reference paper 2016 \"Deep Compression: Compressing Deep Neural Networks with Pruning, Trained Quantization and Huffman Coding\".\n",
    "\n",
    "    Link: https://arxiv.org/abs/1510.00149\n",
    "    \"\"\"\n",
    "\n",
    "    class KmeansCompressData(QuantizedCompressedData):\n",
    "        def __init__(self, compressed_data, quant_bits, origin_type=None, q=None):\n",
    "            super().__init__(compressed_data, quant_bits, origin_type)\n",
    "            self.q = q\n",
    "\n",
    "    def __init__(self, quant_bits: int = 8, n_clusters=None):\n",
    "        super().__init__(quant_bits)\n",
    "        from sklearn.cluster import KMeans\n",
    "\n",
    "        if n_clusters is None:\n",
    "            self.n_clusters = quant_bits\n",
    "        else:\n",
    "            self.n_clusters = n_clusters\n",
    "        self.km = KMeans(self.n_clusters, n_init=1, max_iter=50)\n",
    "\n",
    "    def _compress_one(self, data: np.ndarray, **kwargs) -> \"KmeansCompressData\":\n",
    "        if data.flatten().shape[0] <= self.n_clusters:\n",
    "            return self.KmeansCompressData(data, self.quant_bits)\n",
    "        ori_shape = data.shape\n",
    "        self.km.fit(np.expand_dims(data.flatten(), axis=1))\n",
    "\n",
    "        quantized = self.km.labels_ - (1 << (self.quant_bits - 1))\n",
    "\n",
    "        quantized = np.reshape(quantized, ori_shape)\n",
    "        q = self.km.cluster_centers_\n",
    "\n",
    "        return self.KmeansCompressData(\n",
    "            quantized.astype(self.np_type), self.quant_bits, data.dtype, q\n",
    "        )\n",
    "\n",
    "    def _decompress_one(self, data: \"KmeansCompressData\") -> np.ndarray:\n",
    "        if data.compressed_data.flatten().shape[0] <= self.n_clusters:\n",
    "            return data.compressed_data\n",
    "        label = data.compressed_data.astype(data.origin_type) + (\n",
    "            1 << (self.quant_bits - 1)\n",
    "        )\n",
    "        dequantized = np.zeros_like(label)\n",
    "        for i in range(data.q.shape[0]):\n",
    "            dequantized[label == i] = data.q[i]\n",
    "\n",
    "        return dequantized"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们来实例化这个算法，再跑一遍联邦学习模型："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:root:Create proxy actor <class 'secretflow_fl.ml.nn.sl.backend.tensorflow.sl_base.PYUSLTFModel'> with party alice.\n",
      "INFO:root:Create proxy actor <class 'secretflow_fl.ml.nn.sl.backend.tensorflow.sl_base.PYUSLTFModel'> with party bob.\n",
      "INFO:root:SL Train Params: {'x': VDataFrame(partitions={PYURuntime(alice): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f37c4db5310>), PYURuntime(bob): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f37c4de31c0>)}, aligned=True), 'y': VDataFrame(partitions={PYURuntime(alice): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f37c4675a60>)}, aligned=True), 'batch_size': 128, 'epochs': 40, 'verbose': 1, 'callbacks': None, 'validation_data': (VDataFrame(partitions={PYURuntime(alice): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f3769f921f0>), PYURuntime(bob): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f37c4de3190>)}, aligned=True), VDataFrame(partitions={PYURuntime(alice): Partition(data=<secretflow.device.device.pyu.PYUObject object at 0x7f37c4675dc0>)}, aligned=True)), 'shuffle': True, 'sample_weight': None, 'validation_freq': 1, 'dp_spent_step_freq': None, 'dataset_builder': None, 'audit_log_params': {}, 'random_seed': 91222, 'audit_log_dir': None, 'self': <secretflow_fl.ml.nn.sl.sl_model.SLModel object at 0x7f3554274a30>}\n",
      "\u001b[2m\u001b[36m(pid=30232)\u001b[0m 2023-08-16 01:46:19.445573: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=30250)\u001b[0m 2023-08-16 01:46:19.623566: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=30232)\u001b[0m 2023-08-16 01:46:20.187158: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=30232)\u001b[0m 2023-08-16 01:46:20.187299: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=30232)\u001b[0m 2023-08-16 01:46:20.187315: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n",
      "\u001b[2m\u001b[36m(pid=30250)\u001b[0m 2023-08-16 01:46:20.343446: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=30250)\u001b[0m 2023-08-16 01:46:20.343542: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(pid=30250)\u001b[0m 2023-08-16 01:46:20.343556: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m 2023-08-16 01:46:22.002165: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m 2023-08-16 01:46:22.002204: W tensorflow/compiler/xla/stream_executor/cuda/cuda_driver.cc:265] failed call to cuInit: UNKNOWN ERROR (303)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m Model: \"sequential\"\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m _________________________________________________________________\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m  Layer (type)                Output Shape              Param #   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m =================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m  dense (Dense)               (None, 100)               500       \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m                                                                  \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m  dense_1 (Dense)             (None, 64)                6464      \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m                                                                  \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m =================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m Total params: 6,964\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m Trainable params: 6,964\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m Non-trainable params: 0\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m _________________________________________________________________\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m Model: \"model\"\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m __________________________________________________________________________________________________\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m  Layer (type)                   Output Shape         Param #     Connected to                     \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m ==================================================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m  input_2 (InputLayer)           [(None, 64)]         0           []                               \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m                                                                                                   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m  input_3 (InputLayer)           [(None, 64)]         0           []                               \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m                                                                                                   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m  concatenate (Concatenate)      (None, 128)          0           ['input_2[0][0]',                \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m                                                                   'input_3[0][0]']                \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m                                                                                                   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m  dense_2 (Dense)                (None, 64)           8256        ['concatenate[0][0]']            \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m                                                                                                   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m  dense_3 (Dense)                (None, 1)            65          ['dense_2[0][0]']                \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m                                                                                                   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m ==================================================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m Total params: 8,321\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m Trainable params: 8,321\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m Non-trainable params: 0\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30232)\u001b[0m __________________________________________________________________________________________________\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30250)\u001b[0m 2023-08-16 01:46:22.167943: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30250)\u001b[0m 2023-08-16 01:46:22.167979: W tensorflow/compiler/xla/stream_executor/cuda/cuda_driver.cc:265] failed call to cuInit: UNKNOWN ERROR (303)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30250)\u001b[0m Model: \"sequential\"\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30250)\u001b[0m _________________________________________________________________\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30250)\u001b[0m  Layer (type)                Output Shape              Param #   \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30250)\u001b[0m =================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30250)\u001b[0m  dense (Dense)               (None, 100)               1300      \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30250)\u001b[0m                                                                  \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30250)\u001b[0m  dense_1 (Dense)             (None, 64)                6464      \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30250)\u001b[0m                                                                  \n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30250)\u001b[0m =================================================================\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30250)\u001b[0m Total params: 7,764\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30250)\u001b[0m Trainable params: 7,764\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30250)\u001b[0m Non-trainable params: 0\n",
      "\u001b[2m\u001b[36m(PYUSLTFModel pid=30250)\u001b[0m _________________________________________________________________\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 29/29 [00:13<00:00,  2.39it/s]\u001b[2m\u001b[36m(_run pid=27350)\u001b[0m /tmp/ipykernel_25795/600430472.py:13: ConvergenceWarning: Number of distinct clusters (248) found smaller than n_clusters (256). Possibly due to duplicate points in X.\n",
      "100%|██████████| 29/29 [00:15<00:00,  1.83it/s, epoch: 1/40 -  train_loss:0.4416384696960449  train_accuracy:0.8701704740524292  train_auc_1:0.518036961555481  val_loss:0.40735140442848206  val_accuracy:0.8729282021522522  val_auc_1:0.5592570304870605 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.10it/s, epoch: 2/40 -  train_loss:0.36653003096580505  train_accuracy:0.8817349076271057  train_auc_1:0.5584944486618042  val_loss:0.3673045337200165  val_accuracy:0.8729282021522522  val_auc_1:0.6474628448486328 ]\n",
      "\u001b[2m\u001b[36m(_run pid=27350)\u001b[0m /tmp/ipykernel_25795/600430472.py:13: ConvergenceWarning: Number of distinct clusters (237) found smaller than n_clusters (256). Possibly due to duplicate points in X.\n",
      "100%|██████████| 29/29 [00:11<00:00,  2.35it/s]\u001b[2m\u001b[36m(_run pid=27349)\u001b[0m /tmp/ipykernel_25795/600430472.py:13: ConvergenceWarning: Number of distinct clusters (251) found smaller than n_clusters (256). Possibly due to duplicate points in X.\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.18it/s, epoch: 3/40 -  train_loss:0.32427504658699036  train_accuracy:0.890625  train_auc_1:0.6890991926193237  val_loss:0.35910260677337646  val_accuracy:0.8729282021522522  val_auc_1:0.6932856440544128 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.23it/s, epoch: 4/40 -  train_loss:0.31370726227760315  train_accuracy:0.8875584006309509  train_auc_1:0.7440165281295776  val_loss:0.34864872694015503  val_accuracy:0.8729282021522522  val_auc_1:0.7281122803688049 ]\n",
      "  0%|          | 0/29 [00:00<?, ?it/s]\u001b[2m\u001b[36m(_run pid=27349)\u001b[0m /tmp/ipykernel_25795/600430472.py:13: ConvergenceWarning: Number of distinct clusters (251) found smaller than n_clusters (256). Possibly due to duplicate points in X.\n",
      "100%|██████████| 29/29 [00:12<00:00,  2.24it/s, epoch: 5/40 -  train_loss:0.2876177728176117  train_accuracy:0.8971962332725525  train_auc_1:0.7722644209861755  val_loss:0.33951109647750854  val_accuracy:0.8729282021522522  val_auc_1:0.7569069862365723 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.12it/s, epoch: 6/40 -  train_loss:0.29279187321662903  train_accuracy:0.8887392282485962  train_auc_1:0.7948960065841675  val_loss:0.3284510374069214  val_accuracy:0.8729282021522522  val_auc_1:0.8004623055458069 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.13it/s, epoch: 7/40 -  train_loss:0.27801549434661865  train_accuracy:0.8846591114997864  train_auc_1:0.8384666442871094  val_loss:0.3052524924278259  val_accuracy:0.8696132302284241  val_auc_1:0.815767765045166 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.15it/s, epoch: 8/40 -  train_loss:0.26859837770462036  train_accuracy:0.88606196641922  train_auc_1:0.8598557710647583  val_loss:0.2872508466243744  val_accuracy:0.8773480653762817  val_auc_1:0.8434892296791077 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.16it/s, epoch: 9/40 -  train_loss:0.2744479179382324  train_accuracy:0.8841261267662048  train_auc_1:0.8505929708480835  val_loss:0.3062475025653839  val_accuracy:0.8729282021522522  val_auc_1:0.8401155471801758 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.12it/s, epoch: 10/40 -  train_loss:0.248819500207901  train_accuracy:0.8949353694915771  train_auc_1:0.8706037998199463  val_loss:0.2888694405555725  val_accuracy:0.8751381039619446  val_auc_1:0.8512933850288391 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.17it/s, epoch: 11/40 -  train_loss:0.2316252887248993  train_accuracy:0.908462405204773  train_auc_1:0.875359058380127  val_loss:0.2812938690185547  val_accuracy:0.8806629776954651  val_auc_1:0.8486737012863159 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.16it/s, epoch: 12/40 -  train_loss:0.2373391091823578  train_accuracy:0.9034845232963562  train_auc_1:0.8871505260467529  val_loss:0.2884312868118286  val_accuracy:0.8817679286003113  val_auc_1:0.8496752977371216 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.16it/s, epoch: 13/40 -  train_loss:0.23225976526737213  train_accuracy:0.9103982448577881  train_auc_1:0.8738927841186523  val_loss:0.28070011734962463  val_accuracy:0.8795580267906189  val_auc_1:0.8505558967590332 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.14it/s, epoch: 14/40 -  train_loss:0.2326977550983429  train_accuracy:0.904633641242981  train_auc_1:0.8821461200714111  val_loss:0.2945939600467682  val_accuracy:0.8762431144714355  val_auc_1:0.8517225980758667 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.17it/s, epoch: 15/40 -  train_loss:0.23820573091506958  train_accuracy:0.8987832069396973  train_auc_1:0.8843868374824524  val_loss:0.28626009821891785  val_accuracy:0.8784530162811279  val_auc_1:0.8519262075424194 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.13it/s, epoch: 16/40 -  train_loss:0.2329801470041275  train_accuracy:0.9027478694915771  train_auc_1:0.8967185616493225  val_loss:0.27662354707717896  val_accuracy:0.8762431144714355  val_auc_1:0.8568078875541687 ]\n",
      "100%|██████████| 29/29 [00:14<00:00,  2.05it/s, epoch: 17/40 -  train_loss:0.2397279292345047  train_accuracy:0.9022727012634277  train_auc_1:0.8815232515335083  val_loss:0.2774234414100647  val_accuracy:0.8784530162811279  val_auc_1:0.8531590700149536 ]\n",
      "100%|██████████| 29/29 [00:14<00:00,  2.04it/s, epoch: 18/40 -  train_loss:0.23408104479312897  train_accuracy:0.9023783206939697  train_auc_1:0.8883072137832642  val_loss:0.2731465995311737  val_accuracy:0.8795580267906189  val_auc_1:0.8594001531600952 ]\n",
      "100%|██████████| 29/29 [00:14<00:00,  2.05it/s, epoch: 19/40 -  train_loss:0.23964105546474457  train_accuracy:0.897400438785553  train_auc_1:0.8906112313270569  val_loss:0.28690865635871887  val_accuracy:0.8850829005241394  val_auc_1:0.8540396690368652 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.09it/s, epoch: 20/40 -  train_loss:0.22502458095550537  train_accuracy:0.9051437973976135  train_auc_1:0.9018193483352661  val_loss:0.28959548473358154  val_accuracy:0.8773480653762817  val_auc_1:0.8575343489646912 ]\n",
      "100%|██████████| 29/29 [00:14<00:00,  2.04it/s, epoch: 21/40 -  train_loss:0.2249988317489624  train_accuracy:0.907866358757019  train_auc_1:0.9009451270103455  val_loss:0.2748246490955353  val_accuracy:0.8762431144714355  val_auc_1:0.8615685701370239 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.10it/s, epoch: 22/40 -  train_loss:0.22449716925621033  train_accuracy:0.9081858396530151  train_auc_1:0.8942176699638367  val_loss:0.2766781151294708  val_accuracy:0.8839778900146484  val_auc_1:0.863351583480835 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.09it/s, epoch: 23/40 -  train_loss:0.22895343601703644  train_accuracy:0.9034845232963562  train_auc_1:0.9039328098297119  val_loss:0.28054457902908325  val_accuracy:0.8817679286003113  val_auc_1:0.8572096824645996 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.08it/s, epoch: 24/40 -  train_loss:0.22407710552215576  train_accuracy:0.9059734344482422  train_auc_1:0.9005993008613586  val_loss:0.27575767040252686  val_accuracy:0.8850829005241394  val_auc_1:0.8586461544036865 ]\n",
      "100%|██████████| 29/29 [00:14<00:00,  2.04it/s, epoch: 25/40 -  train_loss:0.23382873833179474  train_accuracy:0.8992456793785095  train_auc_1:0.9045984745025635  val_loss:0.27955323457717896  val_accuracy:0.8795580267906189  val_auc_1:0.8569509983062744 ]\n",
      "100%|██████████| 29/29 [00:14<00:00,  2.05it/s, epoch: 26/40 -  train_loss:0.2256137877702713  train_accuracy:0.903761088848114  train_auc_1:0.9021925926208496  val_loss:0.2896490693092346  val_accuracy:0.8762431144714355  val_auc_1:0.8572261929512024 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.15it/s, epoch: 27/40 -  train_loss:0.20892585813999176  train_accuracy:0.9138434529304504  train_auc_1:0.9012246131896973  val_loss:0.28507480025291443  val_accuracy:0.8784530162811279  val_auc_1:0.854832112789154 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.08it/s, epoch: 28/40 -  train_loss:0.2042495459318161  train_accuracy:0.9186946749687195  train_auc_1:0.9083205461502075  val_loss:0.28037697076797485  val_accuracy:0.8828729391098022  val_auc_1:0.8549861907958984 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.08it/s, epoch: 29/40 -  train_loss:0.2143721729516983  train_accuracy:0.9090154767036438  train_auc_1:0.918034553527832  val_loss:0.28719428181648254  val_accuracy:0.889502763748169  val_auc_1:0.8539240956306458 ]\n",
      "100%|██████████| 29/29 [00:14<00:00,  2.07it/s, epoch: 30/40 -  train_loss:0.23188023269176483  train_accuracy:0.9043141603469849  train_auc_1:0.8931484818458557  val_loss:0.28120020031929016  val_accuracy:0.8795580267906189  val_auc_1:0.8607484102249146 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.08it/s, epoch: 31/40 -  train_loss:0.214926615357399  train_accuracy:0.9139933586120605  train_auc_1:0.9071189165115356  val_loss:0.27989909052848816  val_accuracy:0.8817679286003113  val_auc_1:0.8585194945335388 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.09it/s, epoch: 32/40 -  train_loss:0.19993817806243896  train_accuracy:0.9156526327133179  train_auc_1:0.918624758720398  val_loss:0.29084789752960205  val_accuracy:0.8883978128433228  val_auc_1:0.8593835830688477 ]\n",
      "100%|██████████| 29/29 [00:14<00:00,  2.06it/s, epoch: 33/40 -  train_loss:0.21098265051841736  train_accuracy:0.9143319129943848  train_auc_1:0.910923182964325  val_loss:0.3034096658229828  val_accuracy:0.8806629776954651  val_auc_1:0.8596697449684143 ]\n",
      "100%|██████████| 29/29 [00:14<00:00,  1.98it/s, epoch: 34/40 -  train_loss:0.21316346526145935  train_accuracy:0.908462405204773  train_auc_1:0.9148238897323608  val_loss:0.281110942363739  val_accuracy:0.8850829005241394  val_auc_1:0.8626692891120911 ]\n",
      "100%|██████████| 29/29 [00:14<00:00,  2.06it/s, epoch: 35/40 -  train_loss:0.19225820899009705  train_accuracy:0.9240301847457886  train_auc_1:0.9190618991851807  val_loss:0.29221484065055847  val_accuracy:0.8795580267906189  val_auc_1:0.856224536895752 ]\n",
      "100%|██████████| 29/29 [00:14<00:00,  2.03it/s, epoch: 36/40 -  train_loss:0.21308253705501556  train_accuracy:0.9129849076271057  train_auc_1:0.9214832782745361  val_loss:0.2819535434246063  val_accuracy:0.8839778900146484  val_auc_1:0.8588112592697144 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.09it/s, epoch: 37/40 -  train_loss:0.20776230096817017  train_accuracy:0.9178650379180908  train_auc_1:0.9141819477081299  val_loss:0.2892824411392212  val_accuracy:0.8795580267906189  val_auc_1:0.8580352067947388 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.07it/s, epoch: 38/40 -  train_loss:0.20729485154151917  train_accuracy:0.915099561214447  train_auc_1:0.9170703887939453  val_loss:0.28393277525901794  val_accuracy:0.8861878514289856  val_auc_1:0.8550798296928406 ]\n",
      "100%|██████████| 29/29 [00:13<00:00,  2.10it/s, epoch: 39/40 -  train_loss:0.21065551042556763  train_accuracy:0.9147727489471436  train_auc_1:0.9200801253318787  val_loss:0.3028808534145355  val_accuracy:0.8883978128433228  val_auc_1:0.8555586338043213 ]\n",
      "100%|██████████| 29/29 [00:14<00:00,  2.05it/s, epoch: 40/40 -  train_loss:0.20016591250896454  train_accuracy:0.9172952771186829  train_auc_1:0.9134470224380493  val_loss:0.2854197919368744  val_accuracy:0.8861878514289856  val_auc_1:0.8552834391593933 ]\n"
     ]
    }
   ],
   "source": [
    "qkm = QuantizedKmeans()\n",
    "\n",
    "sl_model_kmeans = SLModel(\n",
    "    base_model_dict=base_model_dict,\n",
    "    device_y=alice,\n",
    "    model_fuse=model_fuse,\n",
    "    compressor=qkm,\n",
    ")\n",
    "\n",
    "history_kmeans = sl_model_kmeans.fit(\n",
    "    train_data,\n",
    "    train_label,\n",
    "    validation_data=(test_data, test_label),\n",
    "    epochs=40,\n",
    "    batch_size=128,\n",
    "    shuffle=True,\n",
    "    verbose=1,\n",
    "    validation_freq=1,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkAAAAHHCAYAAABXx+fLAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAACGhElEQVR4nO3deVhUZfvA8e8w7LvKjogboqi4YBLuJoZapq1qlmhlZdpmm76lZpv96s3MsmzR7E1L08zMTHMvc819RVEUUUEW2feZ8/vjyOgIKAMDA3J/rmsumOc8c+Y+HHRunlWjKIqCEEIIIUQ9YmXpAIQQQgghapokQEIIIYSodyQBEkIIIUS9IwmQEEIIIeodSYCEEEIIUe9IAiSEEEKIekcSICGEEELUO5IACSGEEKLekQRICCGEEPWOJEBC3MI0Gg1vvvmmya87c+YMGo2GBQsWmD2m+kR+jkLUXpIACVHNFixYgEajQaPRsHXr1lLHFUUhICAAjUbD3XffbYEIzWP16tVoNBr8/PzQ6/WWDqdMTZs2Lfdn/O+//94SyUpmZibTp0+nQ4cOODs74+DgQLt27Xjttde4cOGCpcMTotaQBEiIGmJvb88PP/xQqnzLli0kJCRgZ2dngajMZ9GiRTRt2pSLFy+yceNGS4dTL50+fZqOHTvy9ttvExISwv/93/8xe/Zs+vbty7x58+jTp4+lQxSi1pAESIgaMmjQIJYuXUpxcbFR+Q8//EBYWBg+Pj4WiqzqcnJy+PXXX5k4cSKdOnVi0aJFFXqdXq8nPz+/mqO7deTk5JR7rLi4mPvuu4+kpCQ2b97Mjz/+yPjx4xk7diyffvopp0+f5sEHHzRLHPn5+bW2lU+IipIESIgaMmLECFJTU1m3bp2hrLCwkGXLlvHwww+X+ZqcnBxeeuklAgICsLOzIzg4mP/+978oimJUr6CggBdffBFPT09cXFy45557SEhIKPOc58+f57HHHsPb2xs7Ozvatm3L/Pnzq3Rtv/zyC3l5eTz44IMMHz6c5cuXl5nYaDQaJkyYwKJFi2jbti12dnasWbOmwnEVFhYydepUwsLCcHNzw8nJiZ49e7Jp06YqxV+e0aNH4+zszPnz5xk6dCjOzs54enry8ssvo9PpjOqmp6czevRo3NzccHd3Jzo6mvT09DLPe/z4cR544AEaNmyIvb09Xbp0YeXKlUZ1SrpOt2zZwjPPPIOXlxeNGzcuN9aff/6ZAwcO8Prrr9OjR49Sx11dXXn33XcNz5s2bcro0aNL1evTp49RS9HmzZvRaDQsXryYN954A39/fxwdHdm7dy8ajYbvvvuu1DnWrl2LRqNh1apVhrLq+L0ToiqsLR2AEPVF06ZNiYiI4Mcff2TgwIEA/PHHH2RkZDB8+HBmz55tVF9RFO655x42bdrE448/TseOHVm7di2vvPIK58+f5+OPPzbUfeKJJ1i4cCEPP/ww3bp1Y+PGjdx1112lYkhKSuL22283JCKenp788ccfPP7442RmZvLCCy9U6toWLVpE37598fHxYfjw4UyaNInffvutzBaHjRs38tNPPzFhwgQ8PDxo2rRphePKzMzkm2++YcSIEYwdO5asrCzmzZtHVFQUu3btomPHjpWK/0Z0Oh1RUVGEh4fz3//+l/Xr1/PRRx/RokULxo0bB6j3asiQIWzdupWnn36aNm3a8MsvvxAdHV3qfEeOHKF79+74+/szadIknJyc+Omnnxg6dCg///wz9957r1H9Z555Bk9PT6ZOnXrDFqCSBOrRRx8149Vf9fbbb2Nra8vLL79MQUEBISEhNG/enJ9++qnUdS5ZsoQGDRoQFRUFVN/vnRBVogghqtW3336rAMru3buVzz77THFxcVFyc3MVRVGUBx98UOnbt6+iKIoSGBio3HXXXYbXrVixQgGUd955x+h8DzzwgKLRaJTY2FhFURRl//79CqA888wzRvUefvhhBVCmTZtmKHv88ccVX19fJSUlxaju8OHDFTc3N0NccXFxCqB8++23N72+pKQkxdraWvn6668NZd26dVOGDBlSqi6gWFlZKUeOHDEqr2hcxcXFSkFBgVGdy5cvK97e3spjjz1201iv/xlfa/fu3aWuOTo6WgGUt956y6hup06dlLCwMMPzknv1wQcfGMqKi4uVnj17ljpnv379lPbt2yv5+fmGMr1er3Tr1k0JCgoylJX83vTo0UMpLi6+6bV16tRJcXNzu2m9EoGBgUp0dHSp8t69eyu9e/c2PN+0aZMCKM2bNzfchxKTJ09WbGxslLS0NENZQUGB4u7ubnQ/Knp/hahJ0gUmRA166KGHyMvLY9WqVWRlZbFq1apyu79Wr16NVqvlueeeMyp/6aWXUBSFP/74w1APKFXv+r+qFUXh559/ZvDgwSiKQkpKiuERFRVFRkYGe/fuNfmaFi9ejJWVFffff7+hbMSIEfzxxx9cvny5VP3evXsTEhJSqbi0Wi22traAOn4oLS2N4uJiunTpUqnYK+rpp582et6zZ09Onz5teL569Wqsra0NLUIlsT777LNGr0tLS2Pjxo089NBDZGVlGa4zNTWVqKgoTp48yfnz541eM3bsWLRa7U1jzMzMxMXFpTKXVyHR0dE4ODgYlQ0bNoyioiKWL19uKPvzzz9JT09n2LBhQPX93glRVdIFJkQN8vT0JDIykh9++IHc3Fx0Oh0PPPBAmXXPnj2Ln59fqQ+1Nm3aGI6XfLWysqJFixZG9YKDg42eJycnk56ezldffcVXX31V5nteunTJ5GtauHAhXbt2JTU1ldTUVAA6depEYWEhS5cu5cknnzSq36xZsyrF9d133/HRRx9x/PhxioqKyj1vZWk0GqPn9vb2eHp6GpU1aNDAKLk7e/Ysvr6+ODs7G9W7/h7ExsaiKApTpkxhypQpZb7/pUuX8Pf3Nzyv6HW5uroaJWXmVlYcHTp0oHXr1ixZsoTHH38cULu/PDw8uOOOO4Dq+70ToqokARKihj388MOMHTuWxMREBg4ciLu7e428b8msnUceeaTMsSkAoaGhJp3z5MmT7N69G4CgoKBSxxctWlQqAbq+FcGUuBYuXMjo0aMZOnQor7zyCl5eXmi1WmbMmMGpU6duGq+9vT15eXllHsvNzTXUuVZFWl8qquRaX375ZcP4mOu1bNnS6Pn1P6/ytG7dmn379nHu3DkCAgJuWv/6RK+ETqcr85rLi2PYsGG8++67pKSk4OLiwsqVKxkxYgTW1urHS3X83glhDpIACVHD7r33Xp566il27NjBkiVLyq0XGBjI+vXrycrKMmoFOn78uOF4yVe9Xs+pU6eMWhxiYmKMzlcyQ0yn0xEZGWmWa1m0aBE2NjZ8//33pT40t27dyuzZs4mPj6dJkyblnsOUuJYtW0bz5s1Zvny50Qf4tGnTKhRvYGAgR48eLfNYyc+r5OdqisDAQDZs2EB2drZRK9D196B58+YA2NjYmO0elBg8eDA//vgjCxcuZPLkyTet36BBgzJnqZ09e9YQZ0UMGzaM6dOn8/PPP+Pt7U1mZibDhw83HK+O3zshzEHGAAlRw5ydnfniiy948803GTx4cLn1Bg0ahE6n47PPPjMq//jjj9FoNIaZZCVfr59FNmvWLKPnWq2W+++/n59//pnDhw+Xer/k5GSTr2XRokX07NmTYcOG8cADDxg9XnnlFQB+/PHHG57DlLhKkizlmmUAdu7cyfbt2ysU76BBg0hISGDFihVG5QUFBXzzzTd4eXnRuXPnCp3r+vMWFxfzxRdfGMp0Oh2ffvqpUT0vLy/69OnDl19+ycWLF0udpzL3oMQDDzxA+/bteffdd8v8eWRlZfH6668bnrdo0YIdO3ZQWFhoKFu1ahXnzp0z6X3btGlD+/btWbJkCUuWLMHX15devXoZjlfH750Q5iAtQEJYQHldAdcaPHgwffv25fXXX+fMmTN06NCBP//8k19//ZUXXnjBMOanY8eOjBgxgs8//5yMjAy6devGhg0biI2NLXXO999/n02bNhEeHs7YsWMJCQkhLS2NvXv3sn79etLS0ip8DTt37iQ2NpYJEyaUedzf35/OnTuzaNEiXnvttRueq6Jx3X333Sxfvpx7772Xu+66i7i4OObOnUtISAjZ2dk3jfnJJ59k/vz5PPjggzz22GN06tSJ1NRUlixZwuHDh/nf//5nGGRtisGDB9O9e3cmTZrEmTNnCAkJYfny5WRkZJSqO2fOHHr06EH79u0ZO3YszZs3Jykpie3bt5OQkMCBAwdMfn9QW5WWL19OZGQkvXr14qGHHqJ79+7Y2Nhw5MgRfvjhBxo0aGBYC+iJJ55g2bJlDBgwgIceeohTp06xcOHCUmPJKmLYsGFMnToVe3t7Hn/8caysjP+2NufvnRBmY7H5Z0LUE9dOg7+RsqZoZ2VlKS+++KLi5+en2NjYKEFBQcqHH36o6PV6o3p5eXnKc889pzRq1EhxcnJSBg8erJw7d67UNHhFUaetjx8/XgkICFBsbGwUHx8fpV+/fspXX31lqFORafDPPvusAiinTp0qt86bb76pAMqBAwcURVGnwY8fP77MuhWJS6/XK++9954SGBio2NnZKZ06dVJWrVqlREdHK4GBgeXGca3Lly8rL774otKsWTPFxsZGcXV1Vfr27av88ccfpepGR0crTk5OpcqnTZumXP/fZ2pqqvLoo48qrq6uipubm/Loo48q+/btK/PneOrUKWXUqFGKj4+PYmNjo/j7+yt33323smzZMkOdiv7elHV9U6dOVdq3b684Ojoq9vb2Srt27ZTJkycrFy9eNKr70UcfKf7+/oqdnZ3SvXt35d9//y13GvzSpUvLfc+TJ08qgAIoW7duLbNORe6vEDVJoyjXLSkrhBBCCHGLkzFAQgghhKh3JAESQgghRL0jCZAQQggh6h1JgIQQQghR70gCJIQQQoh6RxIgIYQQQtQ7shBiGfR6PRcuXMDFxaXc/XKEEEIIUbsoikJWVhZ+fn6lFuS8niRAZbhw4UKFNhMUQgghRO1z7tw5GjdufMM6kgCVoWTjyXPnzuHq6mrhaIQQQghREZmZmQQEBBhtIF0eSYDKUNLt5erqKgmQEEIIUcdUZPiKDIIWQgghRL0jCZAQQggh6h1JgIQQQghR70gCJIQQQoh6RxIgIYQQQtQ7kgAJIYQQot6RBEgIIYQQ9Y4kQEIIIYSodyQBEkIIIUS9IwmQEEIIIeodSYCEEEIIUe9IAiSEEEKIekcSICGEEKIOKijWkVtYbOkw6izZDV4IIYSoxfR6hXOXczmemEVMySMpi7iUHDTAQ7cF8Hy/ILxd7S0dap0iCZAQQghRS6RmF3DsYhbHEzM5kaQmOyeSsskr0pX7mh92xvPzngRGd2vK071b0MDJttrjzCvUceh8BvvPXWb/uXQOJmTg42rP2F7N6d/GGysrTbXHUFUaRVEUSwdR22RmZuLm5kZGRgaurq6WDkcIIW45+UU6krMKCGjoaPE4/rs2hmK9wjN9WuBVw60oiqJw7GIW644msf5YEofOZ5RZz9baiiAvZ4J9XGjt40Irbxda+7gSn5bLh2uPs/vMZQBc7KwZ26s5j/VohrOdedo49HqFuNQc9sWns//cZfbFp3M8MQudvuz0oZW3M8/0acndob5Ya2t2pI0pn9+SAJVBEiAhhKg+/55J48Wf9pNwOY+5j4QR1dbHInEkZebz5P/+5UCCmnQ42Gh5qndznuzVHEfb6usgKSzWszMulfVHk1h/7BLn0/MMxzQaaNrIiWBvF4J9rj6aNnJCW06riqIobI5J5oO1MRy7mAlAIydbnunbkpHhTbC30ZoUX0p2AQcT0tl/LoP959LZH3+ZzPzSY428XOzo1MSdjgENaO/vxvbTKfxv21myCtS6TRo68nTvFtwf5o+dtWkxVJYkQFUkCZAQQphfYbGeTzac4IvNpyhpPGjS0JF1E3vV2AdkiYMJ6Yz9378kZRbg7mhDYCMnDpxLB9QP9pfubMUDYQHlJh2mysgtYvOJS6w7msSWmGRDkgBgb2NFzyBP+rfxpm9rLzxd7Cr1Hnq9wu+HLjJz3QniUnIA8HOz54XIVtzX2b/M1pis/CIOnc/gYEIGBxPSOXAuwyghK2FnbUV7fzdDwtOpiTu+bvZoNMY/n4y8IhbuOMu8rXGk5RQC4O1qx9iezXk4vEm1JpYgCVCVSQIkhBDmFXspixeW7OfwebWF4r7O/mw9mcKlrALeuKsNT/RsXmOx/HbgAi8vPUBBsZ4gL2e+ie5Ck4aOrD6UyPtrjnEuTU0AWvu4MHlQG3q38jT5PRRFIfZSNltOJLPh2CV2nUkz6jLycLYjso0XkW286RHkYXIrzY0U6fQs25PAJ+tPkpiZD0BzTyde6h+MfwOHK6076ridU8nZXJ8FaDTQ3MOJDo3dDQlPa18XbEzozsor1PHjrni++uu0IYYGjjaM6d6M6IimuDnamO16ryUJUBVJAiSEEOahKAr/236W91Yfo6BYj7ujDTPubc/A9r4s2R3Paz8fwtXemi2v9K32wbt6vcKs9SeYvTEWgL7Bnswe0QkX+6sfxgXFOr7ffpZPN8aSkVcEQM8gD/4zqA1tfG/8eZCZX8S22BS2nEhmS0wyFzLyjY638namf4g3kW286dDYvdoHCucX6Vi44yxzNsVyObeo3Hr+7g6ENnYjtLE7HQLcaO/vZvQzqYqCYh0r9p3ni82nOJOaC4CznTWP3B7I4z2aVbq1qzySAFWRJEBCCFF1SZn5vLLsIH+dSAagVytPPnwg1DBdW6dXuGv23xxPzGJM96ZMG9y22mLJLSxm4pIDrDmSCMDYns2YNLBNuV1c6bmFfLYxlu+2n6FIp6DRwINhjXnpzmBD/Hq9wpELmfx1Uk149sRfNmrlsbW2IrxZQ/oEexHZxovARk7Vdn03kpVfxLytcczfGofWSkOHAHc12bmS9Jg7CSlLsU7P6sOJfL4pluOJWQAMbOfDF4+EmfV9JAGqIkmAhBCiav44dJHJvxwiPbcIO2sr/jOoDaMiAkuNGfn7ZDKPztuFtZWGdRN708zD/EnChfQ8nvjuX45ezMRGq+Hde9vzUJeACr32bGoOH6yJ4fdDFwF1oPQjtzchJbuQv04kk3plnEuJ5p5O9G7lSe9WnoQ3a4SDbc2ObbqRko/76+9BTcew4dglPtsUy7TBIXRq0sCs55cEqIokARJCiMrJyi/izZVH+XlvAgBt/VyZNawjQd4u5b5m9Le72ByTTFRbb758tItZ49lz9jJPfb+HlOwCGjnZ8uWjYXRp2rBS53n396PsjU83Kney1dKtpYch6bH0tP66QlGUaknEJAGqIkmAhBDCdLvPpPHiEnV6u0YD43q34IXIVtha33jw7ImkLAbM+gu9Aj89FUHXZqYnKGVZvjeBST8folCnp7WPC99Ed6Fxg8onKIqi8MfhRFbuv0BTD7WlJyywwU2vT9QcSYCqSBIgIYSouNhL2cxaf4LfD11EUaBxAwc+HtaR20xoaZm8/BA/7oqnQ2M3fnmme5UGCOv0Ch+ujWHullMA3BnizcfDOuJkpoUBRe1lyue3/DYIIYSolDMpOczecJIV+88b1vV5MKwxUweHmDyLaGL/Vqzcf54DCRn8dvACQzr6VyqmYp2eiT8dYOWBCwBM6NuSif1b1YmtGUTNkgRICCHqML1eQa8oNbrlwLm0XD7deJKf9543zHrqH+LNi5GtCPGrXKu5p4sd4/q04L9/nuCDNTFEtfUxeW2cYp2el5aqyY+1lYb/PtiBoZ0ql0iJW58kQEIIUY30eoU/jyaSnltEl6YNaeHpVOXBnynZBWyJSWbziWT+OpFMTkExLTydaeXjQrC3M8E+rgR7u9C4gYNZWz4uZuTx2cZYfvr3HEU6NfHpE+zJxP6tCG3sXuXzP96jOYt2xnM+PY/5/8TxTJ+WFX6tTq/w8tID/LpfTX7mjOxssS02RN1g8TFAc+bM4cMPPyQxMZEOHTrw6aef0rVr1zLrFhUVMWPGDL777jvOnz9PcHAw//d//8eAAQMqfc6yyBggIYQ5JGbk8/LSA2yNTTGUNXKy5bamDbmtWUPCmzWkja/rTbdb0OkVDiakszkmmc0xlzh4PqPU6r1lcbTVEuRtnBS18nHGw8nOpMToUlY+n286xQ+74iks1gPQo6UHL/ZvRVigeacxL9+bwMSfDuBsZ83mV/rg4XzzNWp0eoVXlh5g+b7zWFtp+OzhzgxoJ8lPfVRnBkEvWbKEUaNGMXfuXMLDw5k1axZLly4lJiYGLy+vUvVfe+01Fi5cyNdff03r1q1Zu3YtEydOZNu2bXTq1KlS5yyLJEBC1G2KovDjrnOsPZKIk50WV3sbXB1scLW3vvLVBjcHG1wdrK85ZmPWNVtWHbzA678cJiOvCHsbK0L93TmQkE7BlQSihLOdNZ0DGxDerCG3NW1IaGM37G20XM4p5K+TyWyOSWbLiWTDvkol2vm70qeVF31be+Ltas/JpGyOJ2ZxIimL44lZnLqUTaHO+L1KaDTg5mCDu4P6c3BztMXdwQZ3R7XM1cEG9ytlu86k8b/tZ8gvUs/VtVlDJvZvxe3NG5ntZ3UtvV7hnjlbOXw+k0dvD+Ttoe1uWF+nV3hl2QGW7z2P1krDnIc7MaCdb7XEJmq/OpMAhYeHc9ttt/HZZ58BoNfrCQgI4Nlnn2XSpEml6vv5+fH6668zfvx4Q9n999+Pg4MDCxcurNQ5yyIJkBB1V36Rjv8sP8TyfedNfm2Hxm4807cl/dt4V7rrKDO/iGm/HuGXK+8f2tiNj4d1pIWnM4XFeg6dT2dX3GV2xaXy79nLZF23y7attRWBDR05lZzNNYsK42JnTc9WHvQJ9qJPK0+8rqxGXJ5inZ4zqbnEJGYRk5RFTGImJ5KyOZOaU6HWo+t1auLOS/2D6d6yUbUvpLf9VCojvt6B1krD2hd60tKr7DWEdHqFV5cd5Oe9CWitNHw2ohMD20vyU5/ViVlghYWF7Nmzh8mTJxvKrKysiIyMZPv27WW+pqCgAHt743/0Dg4ObN26tdLnLDlvQUGB4XlmZmalrkkIYVkX0vN4euEeDiZkoLXSML5PCzxc7MjILSIzv4jMvGL16zXfZ+QVkZlXhF6BAwkZPPX9HoK9XRh/R0vuau9r0m7gO06n8tJPBzifnoeVBsb3bclz/YIMm0jaWlsRFtiQsMCGjOvTAp1e4XhiJrvj0th1Jo1dcZdJyS7g5KVsQN2Ms0+wF32DPekc2MCkzSittVa09HKmpZczd3E1KSgs1pOeV0hmXhHpuVceeUWk5xaSkaf+PErKMnILcba35okezekT7FljKwhHtGhEZBtv1h9LYsbq48wbfVupOnq9wqSfryY/s4dL8iNMY7EEKCUlBZ1Oh7e3t1G5t7c3x48fL/M1UVFRzJw5k169etGiRQs2bNjA8uXL0el0lT4nwIwZM5g+fXoVr0gIYUm7z6QxbuEeUrILaeBow5yHO9OtpUeFXqsoCslZBXy3/QzfbTtLTFIWz/24j1nrTjCuTwuGdvK/YfJRUKxj5roTfPXXaRQFmjR05ONhHQgLvPE6OForDW393Gjr58bo7s1QFIW4lBxiL2XTzt8NP3cHk34GFWFrbYWXiz1eLjduQbK0yYNasznmEhuOX2JbbIrRvdTrFSYtP8jSPWry88nwjtwVKsmPME2dWr7yk08+ISgoiNatW2Nra8uECRMYM2YMVlZVu4zJkyeTkZFheJw7d85MEQtR9205kczfJ5MtHcYNLdp5loe/3kFKdiGtfVxYOaFHhZMfUPdG8nK155Wo1vzz2h1M7N8Kd0cbTqfk8Mqyg/T972YW7TxLQbGu1GtPJGUxdM42vtyiJj/DugSw+vmeN01+youjuaczd7b1qZbkpy5p4enMyPAmALzz+zHDdHu9XuE/vxzip38TsNLArGEduTvUz5KhijrKYgmQh4cHWq2WpKQko/KkpCR8fMoeve/p6cmKFSvIycnh7NmzHD9+HGdnZ5o3b17pcwLY2dnh6upq9BCivlMUhf+ujSF6/i4enbeLpf/Wvj8MCov1TF5+iNd/OUyRTuGuUF+WP9OtSvsxuTna8Fy/ILa+dgeTB7bGw9mWhMt5vP7LYXp9sIn5W+PIK9Sh1yvM2xrH3Z9u5djFTBpe2Wfq/x4IxVlWHDaL5/oF4WJnzdGLmSzfm4Ber/D6ikMs3n1OTX6Gd2JwB0l+ROVYLAGytbUlLCyMDRs2GMr0ej0bNmwgIiLihq+1t7fH39+f4uJifv75Z4YMGVLlcwohrirS6Xl56UE+2xRrKJu0/BDrjybd4FU161JWPg9/vYMfd8Wj0cCrA4L5bEQnHG3Nk3w421nzVO8WbH3tDt4cHIKvmz1JmQW8teooPf5vIw/M3cbbq45SWKynT7Ana17oKevOmFkjZzvG36GuBfTfP2OubJehJj8fD+vIPZL8iCqw+DT46OhovvzyS7p27cqsWbP46aefOH78ON7e3owaNQp/f39mzJgBwM6dOzl//jwdO3bk/PnzvPnmm8TFxbF3717c3d0rdM6KkFlgoj7LLihm3MI9/H0yBa2VhneHtmP3mcv8vDcBO2srFj4RbtIeT9XhwLl0nvp+D4mZ+bjYWzN7eCf6tq7YMheVVVCsY/ne83y+OZZzaXkA2NtY8fpdITwS3qTGBgjXN/lFOvp9tIXz6erP3EoDMx/qKCs8izLViVlgAMOGDSM5OZmpU6eSmJhIx44dWbNmjSFRiY+PNxrfk5+fzxtvvMHp06dxdnZm0KBBfP/994bkpyLnFEKU71JWPmO+3c2RC5k42Gj5fGRn+rb24v6wxlzOLWTj8Us8tmA3Pz0VQRtfy/xxsGxPAv/55RCFxXpaeDrx9aguNPd0rvb3tbPWMqJrEx4Ma8zKAxfYfeYyT/RsRosaeO/6zN5Gy2sDW/Pcj/vQaOCjh2R7C2EeFl8JujaSFiBRH51KziZ6/i4SLufRyMmW+aNvo0OAu+F4XqGOR+btZM/Zy3i52PHzuKqNtTFFRl4RsZey+HX/Bf63/SwAkW28+HhYR5M33RR1j6Io/LLvPH7uDtW2AKO4NdSZhRBrK0mARH2z52waj3/3L+m5RTRt5Mh3j3UlsJFTqXoZuUU89OV2YpKyaNrIkWXjulVoq4KKysgt4sSlLE4mZXMiKYvYS9mcvJRFUmaBUb3n7mjJC5Gyw7cQwpgkQFUkCZCoT9YeSeS5H/dRUKynQ4A786O70OgGSU1iRj73f7GN8+l5tPN35cext1eqFUZRFDYev8TfJ1M4eSmLE0nZJGcVlFvfz82elt4ujLo9kMgQ6dIWQpQmCVAVSQIkzK2gWMdP/ybQKcCddv5ulg7H4PvtZ5i28gh6Bfq19uLThys2i+p0cjYPzN1OWk4h3Vo04tsxt2FnXbF9tPR6hT8OJ/LpxpMcT8wqddzf3YGWXs608nYmyMuFIG91NWPp6hJC3IwkQFUkCZAwp7ScQp76/l92n7mMnbUVXz4aRp/g6p2xdDOKovDB2hi+2HwKgBFdA3h7SDusTdhq4WBCOiO+2kFOoY5B7X34dETnG24bodMrrDp4gc82xhq2enCy1XJ/WGPa+bvRytuFll7OsoaOEKLSJAGqIkmAhLnEXsrmsQW7iU/LNZTZaDV8OqIzA9rV/JoxiqKQkl3IjNXHDJuFTuzfimfvaFmpadz/xKYw5tvdFOr0PBzehHeHtit1niKdnhX7zvP55lPEpeQA4GJvzZjuzXise1PcHW2rfmFCCIEkQFUmCZAwh39iU3h64R6y8osJaOjAV4924bONsfx+6CJaKw0fPVh903n1eoULGXnEXso2PE5e+ZqRVwSo+1DNuLc9D90WUKX3+v3gRSb8uBdFUVfundi/FaB2+/28R103J+GyuoaLu6MNT/RoxqhuTXGVLi0hhJnVmXWAhLhV/bgrnikrDlOsV+gS2IAvHw2jkbMds0d0wsFWy7I9Cbz4037yinSM6NqkSu+lKAo749LYc/ayUcKTV1R63yoAjQaaezjxxt0h9DVDV9xdob6k5bZjyorDzN5wEld7a2y0VszdcoqLGfkAeDjbMrZncx65PRAn6eISQtQC8j+REGak0yv835rjfPXXaQCGdPTj/+4Pxd5GHSCstdLwwf2hONho+X7HWSYvP0RuoY7HezSr1PvFpeQw/bcjbI4pvVmpjVZDMw8nWno509LTmZbeLrT0dKa5p5MhHnN59PZA0rIL+Xj9Cd75/Zih3NvVjqd6tWBE1yY42Jr3PYUQoiokARLCTHILi3l+8X7WXdkv68XIVjzXr/TYGisrDW8NaYujrZYv/zrN26uOkldYzIQ7gkx6r882xvLN33EU6vTYaDUMaOdLax91IHFLL2eaNHTExoRBzVX1XL+WpOUU8N32s/i52TOub0seDGts9mRLCCHMQcYAlUHGAAlTJWbk88T/dnP4fCa21lZ8+EAoQzreeHyPoijM3hDLx+tPAPBMnxa8EhV8w8HIiqLw+6GLvPv7MUP3Uu9WnkwbHFIj20HcjKIonErOpklDJ2ytLbbXshCinpIxQELUoMPnM3j8u90kZRbQyMmWr0aFERZ4881CNRoNz0cG4Wir5d3Vx/h88ylyC3VMvTukzBWOTyZlMW3lEbadSgWgcQMHpg1uS2Qbr1qzEadGo6Gll4ulwxBCiJuSBEiIKlh3NInnftxHXpGOIC9n5o++zeT9scb2ao6DrZY3VhxmwbYz5BXqeO++9oY1dbLyi/hk/UkWbDtDsV7BztqKcX1a8HTvFtK9JIQQlSQJkBAmUhSFIxcyWb73PN9ui0NRoGeQB3NGdq701O5Hbg/EwUbLK8sOsOTfc+QV6fjvgx1YdfAC760+Tkq2ukXEnSHeTLk7pMY2IRVCiFuVJEBCVNDJpCx+O3iRVQcucPrKgn4AI8Ob8OY9bas84Pj+sMY42mp5bvE+Vh64wLZTKaRkFwLQzMOJaYNDLL6CtBBC3CokARLiBs6m5rDq4EV+O3DBaN8qO2sr7mjtxX2dG5t1DM7A9r58ZaPlqYV7SMkuxMFGy7P9WvJ4j2YV3mtLCCHEzUkCJMR1LqTn8fvBi/x28AIHEzIM5TZaDb2CPBncwY/IEO9q27Oqb2svljx5OxuPX2JE1yb4uTtUy/sIIUR9JgmQEFckXM7lpZ8OsDMuzVBmpYHuLT0YHOpHVFsf3BxrZvuGTk0a0KlJgxp5LyGEqI8kARICKNbpee7HfeyNT0ejgduaNmRwqC8D2/vi4Wxn6fCEEEKYmSRAQgBf/nWavfHpuNhZ88v47rT0svyigkIIIaqPLNUq6r3D5zP4eJ26GvOb97SV5EcIIeoBSYBEvZZfpOPFJfsp1isMbOfDfZ1vvH2FEEKIW4MkQKJe+2BNDCcvZePhbMe797avNVtKCCGEqF4yBkjUW//EpjD/nzgAPnwglIZOthaOSNRKigLZlyD9LFw+C+ln1K9FedDuPmg1AKxkjSZRjsIri6baOlk2DlGKJECiXsrIK+LlpQcAdSXnvq1lheV6TVEgOQZSTlyT6JR8jYfivLJfd3gZNGwO4eOg48NgJ+PH6jW9HlJiIOFfSNgN5/fApaNgZQ0dRkD356FRC0tHKa7QKIqiWDqI2iYzMxM3NzcyMjJwdXW1dDiiGryweB8r9l+gaSNHVj/fE0db+Vug3inIhri/4ORaOLkOMs/foLIGXP2hQSC4B6pfC7Jg3/eQf2WxTHs36BwN4U+BW+MauYR6Iz8TDi5RW908g8GjlXofrCw8iiP7kprsnP/3yte9UJh1gxdooM1g6PEC+IfVVJT1iimf35IAlUESoNrrUEIGs9afYEgnfwaH+lZqzM6qgxeY8MM+rDSwbFw3OsuCg5ahKOqHRl4aNOsNNvbV/56pp+Dkn3BiLZz9B3SFV49ZO4B326tJjnuTq9+7BYB1GV2kBdlw4EfY8TmknVbLNFpoOxRuHw+N5UOuSvIuw84v1Z9vfobxMWsH8GgJHsFXkyLPYGjYoux7BaDXQUGmei7D48rzolzQFYG+SP167ff6YvV3peT7giy4uF9tHbyejRP4dYLGXdSHfxe4fAb+mQUn1lyt17QndH8BWvYDGXtoNpIAVZEkQLVTbmExA2b9TXxaLgAD2vrw9tB2eLpUfKHCxIx8omb9RUZeEc/d0ZKJdwZXV7iiPLpiOLoCtn8GF/apZfbuEPoQdHoUfEPN917FBXBmq9rCc/JPSDtlfNw9EFpFQdCd0LQH2FRy2xG9Xm1J2j4Hzvx9tTzgdoh4BlrfbTxOSFHUD/esi+oj8yJkJULWBfVrbho4e4JbE3APUJMxtytfHdwrF2Ndkpum/ix3faUmLKAmOl5tIOUkpJ40Tl6vpdFCw2bqvS3ON052Ss5lNho16SpJdBp3Ac82oC2nRTnpKGz7FA79pCZSAN7t1a6xtveW/7oSeZch8TAkHYbEQ5B4ELKS1K5XOxewc73u65WHvevVskYt1STR0q1n1UQSoCqSBKh2emfVUb7ZGoe7ow3Z+cUU6xUaONrw1pB23F2B1iBFUYj+djd/nUimvb8by5/pVuUd3OuFy2fUv3wbtazaX6r5mWqX0Y4vIOOcWmZtDw4N1Q/+Er4d1ESo/YOmf9jritUPhTN/q4nPmX+gKOfqcStrCOwGQVeSHo8g8//1ffGg2mJxaJnaggBq4uIfdiXJuZLsFOdX7vx2rleSoWsSIwf3a1oqbtSKUQSKXn2dV4iaULgF1J4Pw+xkNTHe/Q0UZqtlXiHQ6xUIGXI1idQVq2O0kmPUMTfJJ65+vWEX1BXWDmqX5bUPGwfQ2oLWRv090dqoz0u+t7K5UmYDWjvwDlFbeuzdTL/OjATY/jnsWXD199O9CUQ8C50eUWNJP3slySl5HIaMMlqcKsPeDfw6q7+TjbuoX51vjXGQkgBVkSRAtc+++Mvc/8U29Ap8O+Y2vFzseHnpQY5dVP+iG9DWh3fubXfDbSu+336GKb8ewc7ait+f60FLL5eaCr/uybwIR5bDoaVXW2mcfaB5b7W7qnnvio9zyUiAnXNhz3dX/wJ39ICuY+G2J8ChAZzerCZHx3+/+pe9tb06XqLTo2p3QVkf0nrdlYRnK8T9DfHbS/+V7+wDQf3VhKd5H/Wv4ZqQlah+kO+ep3bzlcWhIbj4gqsvuPiAi5/61aGBOr4k45zazZJxDtLPQW6K+eO0dQbP1moy5BWifrB7hYCTZ811zWQlwbbZ8O98tSsKwKc99H4Ngu+qeIKmKGqCmRyj/t7ZOasf9nbXJjuuYF1LtrfJTVN/P3bOvXpv7d3U6yivtcq9CfiEgnc79Wfk3kT9mRVkXWnlyrryyLz6fUl5frr6sykr+XZrAv6dryZEvh3B1rF0PUVRW1aL86AoX/1aXKCOz0K5miha2agtWobn1tckmDbVlnRLAlRFkgDVLoXFeu7+9G9OJGVzXyd/Zg7raCifsymWOZtib9oadCo5m7tm/01+kZ5pg0MY072ZBa6klsu7DMd+U5OeuL+BK/81aLTqf166AuP6jVpeTYaa9gTHhsbHL+xX/5o/8svV5n6PVhAxHkKHld3dlJOqdg/s/R4uHbla3qApdHwEOgxT4yxJeM5ug4LrxobYuamtPM16qnH5tLfsGIuiPDiyQk2CXHyvJjzOPqaPeyrMUT/Y08+prQHpVxKkwuzSLRVGHzjXHENRxytdOqZ+GJa0Ul3PsZGaCLkFqK/R60DRXfmqVx9lldk6q78Ljg3Vczg2UhM9x0ZXy+zd1NaczAvwzydqS0jJh7JfJzXxaTWg/oyNKcqD/YvU7rHLZ9Qyra2amPqEqr/DPu3VMWpV7QLVFakz087vgYQ96tfk4xj+vZco6UrU69R7U5Snfq1sy+X1NFbQ40XoN9U857uiTiVAc+bM4cMPPyQxMZEOHTrw6aef0rVr13Lrz5o1iy+++IL4+Hg8PDx44IEHmDFjBvb26n8kb775JtOnTzd6TXBwMMePH69wTJIA1S4frzvBJxtO0sjJlvUTe9PguvV6jlzIMGoNGthOHRtU0hpUpNPzwBfbOJCQQY+WHvzvsa5YWdWT/1hvpihPHZh5aJk6RubacRUBt0P7B9SxCbbOcG4nxG2B01vgwl71w85Ao3ZdNe+t/qe9/wfjsTBNe0K3Z6Fl/4r95aco6nvs/R4O/3zjsRt2rmrC07TH1YRH1uWpGF2RmgwlHVEToktH1a9ppyn1gWhWGrWVqzD76u9c49ug96T6PShYVwwJu9QE0aOVmrTWhPxMdVB3wr9qQnR+j9qSdjMarfqHjLWd2q2o0VzT7Vp8TfdrOUl2z5eh3xSzXkqdSYCWLFnCqFGjmDt3LuHh4cyaNYulS5cSExODl1fp/sgffviBxx57jPnz59OtWzdOnDjB6NGjGT58ODNnzgTUBGjZsmWsX7/e8Dpra2s8PDwqHJckQLXH8cRMBn+6lSKdwmcPd+LuUL8y65XVGvT20HbcHerHrPUnmLX+JK721qx9sRe+bpUc6Fqb6fXqB4m+WH0o+qvf64vVv+L0uqvPMy+oXVzHVhmPmfBqqyY97e5XZ0CVJy9dnUV1eovafZUSU7qORqsuFBgxAfw6Vv7aCnPh2Eo1GTq7FWxdIDDimoQn9OaDR4VpCnPVNZEuHVM/CK20V1oCtepf7hqr68qufEWj/j7lpqrdO7lp6vd5aVfLrk9mm3SD3q+q3ZP1NfGpjTIvQGqsOt7Jxl5NcKztriQ89lfGTFUwQVOutCDqCo2TIxuHyo2hulHYdSUBCg8P57bbbuOzzz4DQK/XExAQwLPPPsukSZNK1Z8wYQLHjh1jw4YNhrKXXnqJnTt3snXrVkBNgFasWMH+/fsrHZckQLWDTq9w3+f/cCAhg/4h3nz1aNhNBzofPp/By0sPcDxR/VDv3cqTrbEp6PQKnwzvyJCON9jr6/IZdcqtjcOVJudQaNDMMgNE9Tq13z4nRR0bkJOsfl/e89zU61pkTODWRE162j+gNrFXRuZFdU2duC3qDJVmvSD8afOvh5OXrrZGScJTdxUXqt2Yualq0uQpMzGF+Zjy+W2x/0UKCwvZs2cPkydPNpRZWVkRGRnJ9u3by3xNt27dWLhwIbt27aJr166cPn2a1atX8+ijjxrVO3nyJH5+ftjb2xMREcGMGTNo0qRJubEUFBRQUHB1fENmprmnSorK+PafOA4kZOBib807Q9tVaM2fdv5urJzQg882xfL5pli2nEgGYHAHvxsnP6c3w9LR6n/M17J1Vgcb+l7TD+8VUrFBlLoi9QM777L6F3DeZfW5YVruNd8blZdM1zXD3yZW1lcfJX+lW1mrgxtb9ldnWgV0rfpf3q6+6vicDsOqHvON1Icp4Lc6a1tw8VYfQliQxRKglJQUdDod3t7G/wi8vb3LHa/z8MMPk5KSQo8ePVAUheLiYp5++mn+85//GOqEh4ezYMECgoODuXjxItOnT6dnz54cPnwYF5eyZ/3MmDGj1LghYVlnU3P4759qt8rrg9rg7VrxwaK21lZM7N+KO0O8mfLrYYp0et4eUk7LhqKoU5b/fENtQfHrpLb8JB5U1+wozIZzO9RHCStrdU0Sn/ZqC0d++pW/aNOuSXbSzbPmiJ0bOHlceXiqA0idPMt+but0dcCylXXtmdoshBC1UJ1qR968eTPvvfcen3/+OeHh4cTGxvL888/z9ttvM2WKOpBq4MCBhvqhoaGEh4cTGBjITz/9xOOPP17meSdPnszEiRMNzzMzMwkICKjeixHlUhSFST8fIr9IT0TzRgy7rXL3op2/G7880738CkV58Nvz6hL7AB0ehrs/vjozR1esLriWeAguHri68FjeZXWG0rWzlG7E3k2dBePQQG3BsHc3Xn/E4drn1x0vb0VbIYQQVWKxBMjDwwOtVktSUpJReVJSEj4+PmW+ZsqUKTz66KM88cQTALRv356cnByefPJJXn/9dazK+IvX3d2dVq1aERsbW24sdnZ22NnVknUhBIt3n2P76VTsbax4//72ldru4qbSz8GSkWpio9HCgBnQ9UnjriCt9ZW1UdqoqxSD2mKUeeFqMpR96Upi00Cd4uvQ4Gqy49jw6nRfIYQQtYrFEiBbW1vCwsLYsGEDQ4cOBdRB0Bs2bGDChAllviY3N7dUkqPVqh8u5Y3lzs7O5tSpU6XGCYnaKTEjn/d+PwbAy3cGE9jIyfxvcuYf+GmUOnjYsRE8+J26ZkxFaDTg5q8+ggeYPzYhhBA1wqJdYBMnTiQ6OpouXbrQtWtXZs2aRU5ODmPGjAFg1KhR+Pv7M2PGDAAGDx7MzJkz6dSpk6ELbMqUKQwePNiQCL388ssMHjyYwMBALly4wLRp09BqtYwYMcJi1ykqRlEU3lhxiKyCYjoEuJe9WKGiQHaSOu7F1JYVRVFX5l0zSZ0K7hMKwxepK6kKIYSoVyyaAA0bNozk5GSmTp1KYmIiHTt2ZM2aNYaB0fHx8UYtPm+88QYajYY33niD8+fP4+npyeDBg3n33XcNdRISEhgxYgSpqal4enrSo0cPduzYgaenZ41fnzDNqoMXWX/sEjZaDR/cH4q2rMUKd34Ja15TF78LCIem3SGwu7ps+43GyxQXwO8TYd9C9Xm7B+CeT8te6l0IIcQtz+IrQddGsg5QzUvLKaT/zC2k5hTyQmQQL0S2Kl2pIAtmtS89VR3URboCblOTocDu6n42JVstZF6EJY/A+X/VBdz6v6UuzieLrgkhxC2lTqwDJMS13vrtCKk5hQR7u/BMn5ZlV9r1lZr8NGoJ938D8TvU1YjPblMXVYv7S32AuueRf5iaFB38Se02s3eHB+arS+0LIYSo1yQBEha38XgSK/ZfwEoD//dAKLbWZaxfk5+pbhQI6kaJfp3Ux+3j1LE9yTFXk6Gz/6jL91+7fo9XiDrep2HzmrswIYQQtZYkQMKiCop1vPHLYQAe696MjgHuZVe8tvWn3f3GxzQa8GqtPm57XE2ILp9Rk6H4beqA6Z4vg51ztV6LEEKIukMSIGFR22JTuZCRj6eLHRPvLGPcD6itP9vV/eLo/drNZ39pNNCwmfroNNK8AQshhLglyFr5wqLWHE4EYGA7Hxxty8nHDa0/QaVbf4QQQohKkARIWIxOr7DumLoSeFTbslf/Nrn1RwghhKgASYCExew+k0ZaTiHujjZ0bdaw7EpGrT/31WyAQgghblmSAAmLKen+imzjjY22AjO/pPVHCCGEmUgCJCxCURT+PKImQOV2f+36EvLTpfVHCCGE2UkCJCzi0PkMLmTk42irpWeQR+kK+ZmwTcb+CCGEqB6SAAmLWHul9adPsCf2NmUkNyWtPx6tpPVHCCGE2UkCJCyiZPxPmd1f0vojhBCimkkCJGpc7KUsTiXnYKPV0Le1V+kKO69p/Wl7b43HJ4QQ4tYnCZCocWuPqGv/dG/pgau9jfHB/AxZ90cIIUS1kwRI1LiS7q8BZXV/7fzqSutPsLT+CCGEqDaSAIkadT49j0PnM7DSQGSIt/FBo9afV6X1RwghRLWRBEjUqLVXWn+6NG2Ih7Od8UFp/RFCCFFDJAESNWpteYsfSuuPEEKIGiQJkKgxqdkF7D6TBkBU2+u6v0pmfnm2ltYfIYQQ1U4SIFFj1h9LQq9AO39XGjdwvHpAWn+EEELUMEmARI0pd/bXzi/VJMizNYQMrfnAhBBC1DuSAIkakZVfxD+xqQAMaHdNApR2+ppVn6X1RwghRM2QBEjUiE0xyRTq9DT3dKKll4tamH0Jvr8XCjLAr7O0/gghhKgxkgCJGrH2+u6v/ExYeD9cPgMNmsKIxdL6I4QQosZIAiSqXX6Rjk0xl4Ar09+LC2DJSEg8CE6e8MhycPG+yVmEEEII87G2dADi1rf1ZAq5hTp83ewJ9XOGnx+HuL/A1hlGLoNGLSwdohBCiHpGWoBEtTMsfhjijWbNJDi6AqxsYPgi8Oto0diEEELUT5IAiWpVrNOz7pi6+/tj+p9h99eABu77Cpr3sWhsQggh6i/pAhPValdcGum5RTzusIUmB75UCwd+AO3us2xgQggh6jVpARLVau2RRKKsdvO68rVa0OsVCH/SskEJIYSo9yQBEtVGr1dIOrSR2TafYYUeOo+Cvq9bOiwhhBDC8gnQnDlzaNq0Kfb29oSHh7Nr164b1p81axbBwcE4ODgQEBDAiy++SH5+fpXOKarHiUM7+KBoBnaaInSt7oK7PgaNxtJhCSGEEJZNgJYsWcLEiROZNm0ae/fupUOHDkRFRXHp0qUy6//www9MmjSJadOmcezYMebNm8eSJUv4z3/+U+lzimpy+Qz+qx7BVZNLrEMo2gfngVaGnAkhhKgdNIqiKJZ68/DwcG677TY++0zdC0qv1xMQEMCzzz7LpEmTStWfMGECx44dY8OGDYayl156iZ07d7J169ZKnbMsmZmZuLm5kZGRgaura1Uvs/7JSUGZdyeatFMc0wdwZvAyBt7W2tJRCSGEuMWZ8vltsRagwsJC9uzZQ2Rk5NVgrKyIjIxk+/btZb6mW7du7Nmzx9Cldfr0aVavXs2gQYMqfU6AgoICMjMzjR6iCv6cgibtFAmKB2N1k+kZ2tLSEQkhhBBGLNYnkZKSgk6nw9vbeAsEb29vjh8/XuZrHn74YVJSUujRoweKolBcXMzTTz9t6AKrzDkBZsyYwfTp06t4RQKA4kI4vgqAiYXjCA5uhbOddH0JIYSoXSw+CNoUmzdv5r333uPzzz9n7969LF++nN9//5233367SuedPHkyGRkZhse5c+fMFHE9FPcXFGSSqmnIbiVY3ftLCCGEqGUs9qe5h4cHWq2WpKQko/KkpCR8fMr+0JwyZQqPPvooTzzxBADt27cnJyeHJ598ktdff71S5wSws7PDzs6uilckADi2EoDfi8LQaKyIDJFNToUQQtQ+FmsBsrW1JSwszGhAs16vZ8OGDURERJT5mtzcXKysjEPWarUAKIpSqXMKM9Lr4PjvAKzVd6Frs4Y0dLK1cFBCCCFEaRYdnDFx4kSio6Pp0qULXbt2ZdasWeTk5DBmzBgARo0ahb+/PzNmzABg8ODBzJw5k06dOhEeHk5sbCxTpkxh8ODBhkToZucU1ejcTshNIQNndurbMLW9r6UjEkIIIcpk0QRo2LBhJCcnM3XqVBITE+nYsSNr1qwxDGKOj483avF544030Gg0vPHGG5w/fx5PT08GDx7Mu+++W+Fzimp07DcA1us64dfQlYe6BFg4ICGEEKJslV4HqLCwkLi4OFq0aIG19a01y0fWAaoERaHwo3bYZicwtnAiI6PH0SfYy9JRCSGEqEeqdR2g3NxcHn/8cRwdHWnbti3x8fEAPPvss7z//vuVi1jUefoL+7HNTiBXscOxTX9JfoQQQtRqJidAkydP5sCBA2zevBl7e3tDeWRkJEuWLDFrcKLuOLZxEQBb6cjkezpbOBohhBDixkzuu1qxYgVLlizh9ttvR3PNxpZt27bl1KlTZg1O1A1pOYXYn/oDAJt2Q/Bxs7/JK4QQQgjLMrkFKDk5GS+v0t0bOTk5RgmRqD+++WUtLUigCGt6DnrY0uEIIYQQN2VyAtSlSxd+//13w/OSpOebb76RtXbqod1n0lCOqVtf5Pp3x9qpgYUjEkIIIW7O5C6w9957j4EDB3L06FGKi4v55JNPOHr0KNu2bWPLli3VEaOopYp0et745TD/p1U3p3XrdK+FIxJCCCEqxuQWoB49erB//36Ki4tp3749f/75J15eXmzfvp2wsLDqiFHUUvO3xpGZdIaOVqdR0EDruywdkhBCCFEhlVrAp0WLFnz99dfmjkXUIefT85i1/iQPaf8FQNMkApxl6rsQQoi6weQWoMjISBYsWEBmZmZ1xCPqiOkrj5BXpONBp31qQZu7LRuQEEIIYQKTE6C2bdsyefJkfHx8ePDBB/n1118pKiqqjthELbXhWBJ/Hk3C0yqLtkWH1cLWkgAJIYSoO0xOgD755BPOnz/PihUrcHJyYtSoUXh7e/Pkk0/KIOh6IK9Qx7SVRwB4MzgejaIHn1BoEGjhyIQQQoiKMzkBArCysuLOO+9kwYIFJCUl8eWXX7Jr1y7uuOMOc8cnaplPN54k4XIe/u4ODNDuVgvb3GPZoIQQQggTVWkX08TERBYvXszChQs5ePAgXbt2NVdcohaKvZTF13+fBuCtAU3Q/rZZPdBmsMViEkIIISrD5BagzMxMvv32W/r3709AQABffPEF99xzDydPnmTHjh3VEaOoBRRF4Y0VhynSKUS28aKf9QHQFUKjluAZbOnwhBBCCJOY3ALk7e1NgwYNGDZsGDNmzKBLly7VEZeoZX7Zd54dp9Owt7Fi2uC2sOFz9UCbwSBboAghhKhjTEqAFEVh9uzZjBw5EkdHx+qKSdQyGXlFvLf6GADP9QsiwMUKTv6pHmwt3V9CCCHqHpO6wBRFYfz48Zw/f7664hG10IJ/zpCSXUgLTyee6NEcTm+Gwmxw9Qe/TpYOTwghhDCZSQmQlZUVQUFBpKamVlc8opbJyi9i3lZ14PMLka2wtbaC47+pB1vfBVaVmkgohBBCWJTJn17vv/8+r7zyCocPH66OeEQt87/tZ8nML6aFpxOD2vuCrhiOr1YPyuwvIYQQdZTJg6BHjRpFbm4uHTp0wNbWFgcHB6PjaWlpZgtOWFZOQTHfXJn2/uwdQWitNBC3HfLSwKEhNOlm4QiFEEKIyjE5AZo1a1Y1hCFqo4U7znI5t4hmHk7cHeqrFh670v0VPAi0VVpGSgghhLAYkz/BoqOjqyMOUcvkFer46i+19eeZPi2w1lqBosDxVWoF6f4SQghRh5mcAMXHx9/weJMmTSodjKg9Fu08S2pOIQENHRjayV8tvLAXMs+DrTM072PR+IQQQoiqMDkBatq0KZobLHyn0+mqFJCwvPwiHV9eaf0Z36clNtorY+VLur+C+oONvYWiE0IIIarO5ARo3759Rs+LiorYt28fM2fO5N133zVbYMJyluw+R3JWAf7uDtzXubFaqChXEyDp/hJCCFHHmZwAdejQoVRZly5d8PPz48MPP+S+++4zS2DCMgqKdXyx+RQA4/q0UNf9AUiOgdRY0NpCy/4WjFAIIYSoOrOtYhccHMzu3bvNdTphIUv/TSAxMx8fV3se7NL46oGS1p/mfcHe1TLBCSGEEGZicgtQZmam0XNFUbh48SJvvvkmQUFBZgtM1LzCYr2h9efp3s2xs9ZePViy+nObuy0QmRBCCGFeJidA7u7upQZBK4pCQEAAixcvNltgouYt35vA+fQ8PF3sGN71mtl8aafh4gHQWKnr/wghhBB1nMkJ0KZNm4yeW1lZ4enpScuWLbG2loXx6qoinZ45m2MBeKpXc+xtrmn92faZ+rV5X3DysEB0QgghhHmZPAaod+/eRo+ePXvSunXrKiU/c+bMoWnTptjb2xMeHs6uXbvKrdunTx80Gk2px1133WWoM3r06FLHBwwYUOn46oNf91/gXFoeHs62jAwPvHog8yLs+179vudEywQnhBBCmFmFE6A9e/bQt2/fUmOAADIyMujbty8HDhwwOYAlS5YwceJEpk2bxt69e+nQoQNRUVFcunSpzPrLly/n4sWLhsfhw4fRarU8+OCDRvUGDBhgVO/HH380Obb6olinZ84mtfVnbM/mONhe0/qz/TPQFUKTCAjsbqEIhRBCCPOqcAL00Ucfcccdd+DqWnoGkJubG/379+fDDz80OYCZM2cyduxYxowZQ0hICHPnzsXR0ZH58+eXWb9hw4b4+PgYHuvWrcPR0bFUAmRnZ2dUr0GDBibHVl+sOniRuJQcGjja8Mjt17T+5KTCv1fuQ8+X4QYLYAohhBB1SYUToJ07dzJkyJByjw8ePJht27aZ9OaFhYXs2bOHyMjIqwFZWREZGcn27dsrdI558+YxfPhwnJycjMo3b96Ml5cXwcHBjBs3jtTUVJNiqy90eoVPN54E4ImezXGyu6Yrc8fnUJQLvh2hZT/LBCiEEEJUgwoP3Dl//jwuLi7lHnd2dubixYsmvXlKSgo6nQ5vb2+jcm9vb44fP37T1+/atYvDhw8zb948o/IBAwZw33330axZM06dOsV//vMfBg4cyPbt29FqtaXOU1BQQEFBgeF5Wd18t6rVhy5yKjkHV3trRkVc0/qTlw67vlK/7yWtP0IIIW4tFU6APD09iYmJoVmzZmUeP378OB4eNTtDaN68ebRv356uXbsalQ8fPtzwffv27QkNDaVFixZs3ryZfv1Kt2TMmDGD6dOnV3u8tY1er/DZRnXsz+M9muNib3P14O6voSATPNtA8F3lnEEIIYSomyrcBRYZGVnuXl+KovDuu+8adWVVhIeHB1qtlqSkJKPypKQkfHx8bvjanJwcFi9ezOOPP37T92nevDkeHh7ExsaWeXzy5MlkZGQYHufOnav4RdRhfx5NJCYpCxc7a0Z3b3r1QGEObP9c/b7nS2BltgXDhRBCiFqhwp9sb7zxBocOHSI8PJyffvqJAwcOcODAAZYsWUJ4eDiHDx/m9ddfN+nNbW1tCQsLY8OGDYYyvV7Phg0biIiIuOFrly5dSkFBAY888shN3ychIYHU1FR8fX3LPG5nZ4erq6vR41anKAqfbFATwjHdm+LmcE3rz7/fQl4aNGgGbe+1UIRCCCFE9alwF1iLFi1Yv349o0ePZvjw4YbVoBVFISQkhHXr1tGyZUuTA5g4cSLR0dF06dKFrl27MmvWLHJychgzZgwAo0aNwt/fnxkzZhi9bt68eQwdOpRGjRoZlWdnZzN9+nTuv/9+fHx8OHXqFK+++iotW7YkKirK5PhuVeuPXeLYxUycbLU81uOabs2ifNj2qfp9z4mglcUthRBC3HpM+nTr0qULhw8fZv/+/Zw8eRJFUWjVqhUdO3asdADDhg0jOTmZqVOnkpiYSMeOHVmzZo1hYHR8fDxW13XBxMTEsHXrVv78889S59NqtRw8eJDvvvuO9PR0/Pz8uPPOO3n77bexs7OrdJy3mnlbTwMwqltT3B1trx7YvwiyE8G1MYQOL+fVQgghRN2mURRFsXQQtU1mZiZubm5kZGTckt1heYU6QqevpUinsOWVPgQ2urKEgK4IZneGjHgY+CGEP2nZQIUQQggTmPL5LaNb66F/z6ZRpFPwc7OnSUPHqwcOLVWTHycv6Pyo5QIUQgghqpkkQPXQjtPqopC3t2hkGMuFXgd/f6R+HzEebBwsFJ0QQghR/SQBqoe2n7qSADW/ZgD50V8hNRbs3eG2my8tIIQQQtRlJiVAxcXFvPXWWyQkJFRXPKKa5RQUczAhA4CIkgRIUa62/tw+DuzKX/FbCCGEuBWYlABZW1vz4YcfUlxcXF3xiGr279nLFOsVGjdwIKBk/M+JNZB0GGxdoKsMfBZCCHHrM7kL7I477mDLli3VEYuoAaW6vxQF/vqv+v1tj4NjQwtFJoQQQtQck1e5GzhwIJMmTeLQoUOEhYWV2oX9nnvuMVtwwvy2XxkAbej+Or0Zzv8L1g4QMcFygQkhhBA1yOQE6JlnngFg5syZpY5pNBp0Ol3VoxLVIiu/iMPnr4z/aXElASoZ+xMWDc6eFopMCCGEqFkmJ0B6vb464hA14N8zl9HpFQIbOeLn7gDxO+DM32BlA92es3R4QgghRI2p0jT4/Px8c8UhakBJ99ftza60/pSM/en4MLj5WygqIYQQouaZnADpdDrefvtt/P39cXZ25vRpdU+pKVOmMG/ePLMHKMynZAB0RItGcGEfxK4DjRX0eMGygQkhhBA1zOQE6N1332XBggV88MEH2Npe3USzXbt2fPPNN2YNTphPRl4RRy6o439ub94Itn6sHmj/IDRsbsHIhBBCiJpncgL0v//9j6+++oqRI0ei1WoN5R06dOD48eNmDU6Yz+64NPQKNPNwwscqHY6tUg90f96icQkhhBCWYHICdP78eVq2bFmqXK/XU1RUZJaghPkZxv80bwT7FoKig4DbwbuthSMTQgghap7JCVBISAh///13qfJly5bRqVMnswQlzM8w/qd5A9j7nVoYNtpyAQkhhBAWZPI0+KlTpxIdHc358+fR6/UsX76cmJgY/ve//7Fq1arqiFFUUXpuIccSMwHopT0M6fFg7wZth1o2MCGEEMJCTG4BGjJkCL/99hvr16/HycmJqVOncuzYMX777Tf69+9fHTGKKtoZl4aiQAtPJ9yPLlILQ4eDjYNlAxNCCCEsxOQWIICePXuybt06c8ciqklJ91f/JsCx1WphWLTlAhJCCCEsrEoLIYq6YceVAdBD2QL6YmjcVQY/CyGEqNcq1ALUoEEDNBpNhU6YlpZWpYCEeaXlFHI8MQsNeoISflYLZfCzEEKIeq5CCdCsWbMM36empvLOO+8QFRVFREQEANu3b2ft2rVMmTKlWoIUlbfzSuvPQ41Oo804C3Zu0PZeC0clhBBCWFaFEqDo6KvjRe6//37eeustJkyYYCh77rnn+Oyzz1i/fj0vvvii+aMUlVay/s+jNpvVgtCHwNbRcgEJIYQQtYDJY4DWrl3LgAEDSpUPGDCA9evXmyUoYT47TqfiQQYhGX+pBTL4WQghhDA9AWrUqBG//vprqfJff/2VRo0amSUoYR4p2QWcSMrmAe0WrJRi8O8CPu0tHZYQQghhcSZPg58+fTpPPPEEmzdvJjw8HICdO3eyZs0avv76a7MHKCpvx+lUNOgZZbcF9ECXMZYOSQghhKgVTE6ARo8eTZs2bZg9ezbLly8HoE2bNmzdutWQEInaYcfpVCKsjuKnvwh2rjL4WQghhLiiUgshhoeHs2jRInPHIsxs+6lUXtRuVJ+EPgS2TpYNSAghhKglKpUA6fV6YmNjuXTpEnq93uhYr169zBKYqJpLmfmkJ1/gTrvdaoGs/SOEEEIYmJwA7dixg4cffpizZ8+iKIrRMY1Gg06nM1twovK2n07lfu1f2Gp04B8mg5+FEEKIa5icAD399NN06dKF33//HV9f3wqvEC1q1o5TqTxZ0v0lrT9CCCGEEZMToJMnT7Js2TJatmxZHfEIM8k/uZlmVkkUWzth3fY+S4cjhBBC1ComrwMUHh5ObGysWYOYM2cOTZs2xd7envDwcHbt2lVu3T59+qDRaEo97rrrLkMdRVGYOnUqvr6+ODg4EBkZycmTJ80ac22WmJFP3xx113d9+wfBztnCEQkhhBC1i8ktQM8++ywvvfQSiYmJtG/fHhsbG6PjoaGhJp1vyZIlTJw4kblz5xIeHs6sWbOIiooiJiYGLy+vUvWXL19OYWGh4XlqaiodOnTgwQcfNJR98MEHzJ49m++++45mzZoxZcoUoqKiOHr0KPb29iZecd2z99hJoqzUwc+2XR+zcDRCCCFE7aNRrh/JfBNWVqUbjTQaDYqiVGoQdHh4OLfddhufffYZoM4wCwgI4Nlnn2XSpEk3ff2sWbOYOnUqFy9exMnJCUVR8PPz46WXXuLll18GICMjA29vbxYsWMDw4cNves7MzEzc3NzIyMjA1dXVpOupDVbN/Q93J87hglMb/F7ZYelwhBBCiBphyue3yS1AcXFxlQ7seoWFhezZs4fJkycbyqysrIiMjGT79u0VOse8efMYPnw4Tk5OhvgSExOJjIw01HFzcyM8PJzt27eXmQAVFBRQUFBgeJ6ZmVnZS7I8RSE06RcAMkNG4mfhcIQQQojayOQEKDAw0GxvnpKSgk6nw9vb26jc29ub48eP3/T1u3bt4vDhw8ybN89QlpiYaDjH9ecsOXa9GTNmMH36dFPDr5WSj2ykiXKBbMUe/x4jLR2OEEIIUStVOAGaPXt2meVubm60atWKiIgIswVVUfPmzaN9+/Z07dq1SueZPHkyEydONDzPzMwkICCgquFZRN52NRnc6tCXAW4NLRyNEEIIUTtVOAH6+OOPyyxPT08nIyODbt26sXLlSho2rPiHroeHB1qtlqSkJKPypKQkfHx8bvjanJwcFi9ezFtvvWVUXvK6pKQkfH19jc7ZsWPHMs9lZ2eHnZ1dheOutXJS8bvwJwAXWw6zcDBCCCFE7VXhafBxcXFlPi5fvkxsbCx6vZ433njDpDe3tbUlLCyMDRs2GMr0ej0bNmy4aYvS0qVLKSgo4JFHHjEqb9asGT4+PkbnzMzMZOfOnRZppapRB37EWinikL4pzUN7WDoaIYQQotYyeR2gsjRv3pz333+fP//80+TXTpw4ka+//prvvvuOY8eOMW7cOHJychgzZgwAo0aNMhokXWLevHkMHTqURo0aGZVrNBpeeOEF3nnnHVauXMmhQ4cYNWoUfn5+DB06tFLXVycoCkW75wOwRN+PLoENLByQEEIIUXtVajPUsjRp0qTcQcY3MmzYMJKTk5k6dSqJiYl07NiRNWvWGAYxx8fHl5p6HxMTw9atW8tNuF599VVycnJ48sknSU9Pp0ePHqxZs+bWXgMofgc2l0+Ro9gR5zMQJzuz3VohhBDilmPyOkDl+e2335g0aRJHjhwxx+ksqk6uA7RmMuz4nJ91PTnd47+8EtXa0hEJIYQQNapa1gEqb22cjIwM9uzZw0svvUR0dLRpkQrzUBSUmD/QAH/qwni0uYelIxJCCCFqtQonQO7u7uXu/K7RaHjiiScqtHKzqAbJMWgux1GgWLND04FZMv5HCCGEuKEKJ0CbNm0qs9zV1ZWgoCCcnWXDTYs58QcA2/VtaeHvjYOt1sIBCSGEELVbhROg3r17V2ccoipi1ARovb4zgY2cLByMEEIIUfuZZRq8sKCcFDi3C4ANus74uN3CM92EEEIIM5EEqK47sRZQiLdtyUUa4eMqCZAQQghxM5IA1XVXxv9ss1b3Q/OWBEgIIYS4KUmA6rKifIjdCMAfhZ0ApAtMCCGEqABJgOqyM39DUQ6Kiy9bc/0B8JUESAghhLipSu2XsGzZMn766Sfi4+MpLCw0OrZ3716zBCYq4Mrsr7xm/dElg9ZKg4fzLbCrvRBCCFHNTG4Bmj17NmPGjMHb25t9+/bRtWtXGjVqxOnTpxk4cGB1xCjKoihwYg0AF336AuDpbIfWquzFKoUQQghxlckJ0Oeff85XX33Fp59+iq2tLa+++irr1q3jueeeIyMjozpiFGVJPAiZ58HGkVNOYQB4S/eXEEIIUSEmJ0Dx8fF069YNAAcHB7KysgB49NFH+fHHH80bnSjfle4vWtzBxRx1P1sfV+n+EkIIISrC5ATIx8eHtLQ0AJo0acKOHTsAiIuLw0wby4uKKEmAWg0gMTMfAF83BwsGJIQQQtQdJidAd9xxBytXrgRgzJgxvPjii/Tv359hw4Zx7733mj1AUYbMC3BxP6CBVlEkZqgJkKwBJIQQQlSMybPAvvrqK/R6PQDjx4+nUaNGbNu2jXvuuYennnrK7AGKMlwZ/EzjLuDsRWLGaQB83KQLTAghhKgIkxMgKysrrKyuNhwNHz6c4cOHmzUocRMl3V/B6qy7pExpARJCCCFMUamFEP/++28eeeQRIiIiOH/+PADff/89W7duNWtwogyFOXB6i/p9q4EoimIYAyT7gAkhhBAVY3IC9PPPPxMVFYWDgwP79u2joKAAgIyMDN577z2zByiuc2oT6ArAPRC82pBVUExuoQ6QbTCEEEKIijI5AXrnnXeYO3cuX3/9NTY2Noby7t27yyrQNcHQ/TUINBrDAGhXe2scbSu1sLcQQghR75icAMXExNCrV69S5W5ubqSnp5sjJlEeve7qAOjgAQCGBEhaf4QQQoiKq9Q6QLGxsaXKt27dSvPmzc0SlCjH+T2QmwJ2bhDYHcAw/kcGQAshhBAVZ3ICNHbsWJ5//nl27tyJRqPhwoULLFq0iJdffplx48ZVR4yiREn3V8t+oFW7H5MyShZBlARICCGEqCiTB41MmjQJvV5Pv379yM3NpVevXtjZ2fHyyy/z7LPPVkeMosS143+ukBlgQgghhOlMSoB0Oh3//PMP48eP55VXXiE2Npbs7GxCQkJwdnaurhgFQFocJB8DjRaCIg3FhlWgpQVICCGEqDCTEiCtVsudd97JsWPHcHd3JyQkpLriEtcrGfwc2A0cGhiKpQVICCGEMJ3JY4DatWvH6dOnqyMWcSPXbH56LVkFWgghhDBdpdYBevnll1m1ahUXL14kMzPT6CGqQV46nP1H/f7K9hcAhcV6UrILARkELYQQQpjC5EHQgwapA3DvueceNBqNoVxRFDQaDTqdznzRCVXsetAXg0cwNGphKL6Upbb+2GqtaOhka6nohBBCiDrH5ARo06ZN1RGHuJHrFj8sUTIA2svVzigZFUIIIcSNmZwA9e7du9xjhw8frlIwogy6Ijj5p/r9NdPfQQZACyGEEJVVqd3gr5WVlcVXX31F165d6dChg8mvnzNnDk2bNsXe3p7w8HB27dp1w/rp6emMHz8eX19f7OzsaNWqFatXrzYcf/PNN9FoNEaP1q1bmxxXrRG/A/IzwLERNL7N6JBMgRdCCCEqp9K7Z/7111/MmzePn3/+GT8/P+677z7mzJlj0jmWLFnCxIkTmTt3LuHh4cyaNYuoqChiYmLw8vIqVb+wsJD+/fvj5eXFsmXL8Pf35+zZs7i7uxvVa9u2LevXrzc8t7auw5uElsz+CooCK63RoZIZYL7SAiSEEEKYxKTMIDExkQULFjBv3jwyMzN56KGHKCgoYMWKFZVaE2jmzJmMHTuWMWPGADB37lx+//135s+fz6RJk0rVnz9/PmlpaWzbts2wE33Tpk1LX5S1NT4+PibHU+soCsRcad26bvwPQGJmASAboQohhBCmqnAX2ODBgwkODubgwYPMmjWLCxcu8Omnn1b6jQsLC9mzZw+RkVdXNbaysiIyMpLt27eX+ZqVK1cSERHB+PHj8fb2pl27drz33nulZp6dPHkSPz8/mjdvzsiRI4mPj79hLAUFBbVzOn/KCbgcB1pbaHFHqcOJGXmArAEkhBBCmKrCCdAff/zB448/zvTp07nrrrvQarU3f9ENpKSkoNPp8Pb2Nir39vYmMTGxzNecPn2aZcuWodPpWL16NVOmTOGjjz7inXfeMdQJDw9nwYIFrFmzhi+++IK4uDh69uxJVlZWubHMmDEDNzc3wyMgIKBK12Y2Jd1fTXuCnUupw4ZB0NICJIQQQpikwgnQ1q1bycrKIiwsjPDwcD777DNSUlKqM7ZS9Ho9Xl5efPXVV4SFhTFs2DBef/115s6da6gzcOBAHnzwQUJDQ4mKimL16tWkp6fz008/lXveyZMnk5GRYXicO3euJi7n5gybnw4sdUhRFJJKusCkBUgIIYQwSYUToNtvv52vv/6aixcv8tRTT7F48WL8/PzQ6/WsW7fuhi0sZfHw8ECr1ZKUlGRUnpSUVO74HV9fX1q1amXU+tSmTRsSExMpLCws8zXu7u60atWK2NjYcmOxs7PD1dXV6GFxeh1c2Kt+X0b31+XcIgqL9YB0gQkhhBCmMnkavJOTE4899hhbt27l0KFDvPTSS7z//vt4eXlxzz33VPg8tra2hIWFsWHDBkOZXq9nw4YNRERElPma7t27Exsbi16vN5SdOHECX19fbG3LXgk5OzubU6dO4evrW+HYaoX0s6ArBGt7aNC01OGSKfCNnGyxta7yagZCCCFEvVKlT87g4GA++OADEhIS+PHHH01+/cSJE/n666/57rvvOHbsGOPGjSMnJ8cwK2zUqFFMnjzZUH/cuHGkpaXx/PPPc+LECX7//Xfee+89xo8fb6jz8ssvs2XLFs6cOcO2bdu499570Wq1jBgxoiqXWvNSTqpfG7UsNf0dIDFTBkALIYQQlWWWBXK0Wi1Dhw5l6NChJr1u2LBhJCcnM3XqVBITE+nYsSNr1qwxDIyOj4/HyupqjhYQEMDatWt58cUXCQ0Nxd/fn+eff57XXnvNUCchIYERI0aQmpqKp6cnPXr0YMeOHXh6eprjUmtOcoz61aNVmYcTM2QKvBBCCFFZFl8hcMKECUyYMKHMY5s3by5VFhERwY4dO8o93+LFi80VmmWlnFC/lpcAyQwwIYQQotJk8EhtVdIF5hFU5uGkDNkHTAghhKgsSYBqI0WBlJt0gclGqEIIIUSlSQJUG+WmQt5lQKMOgi6DbIQqhBBCVJ4kQLVRyfgf9wCwdSyzirQACSGEEJUnCVBtdJMB0PlFOjLyigAZBC2EEEJUhiRAtVFySQIUXObhku4vBxstrvYWn8gnhBBC1DmSANVGhhagsmeAXcy4OgVeo9HUVFRCCCHELUMSoNroJl1gSVfG/3i72tVUREIIIcQtRRKg2qYoD9Lj1e9lCrwQQghRLSQBqm1SYwEFHBqAk0eZVRINXWAONRiYEEIIceuQBKi2ubb7q5zxPUmGFiDpAhNCCCEqQxKg2ib5xgOgwXgQtBBCCCFMJwlQbZNy4ynwcO0gaEmAhBBCiMqQBKi2MWyCWvYAaJ1e4VJWAQC+MgZICCGEqBRJgGoTvR5Sb7wLfGp2ATq9gpUGPJxtazA4IYQQ4tYhCVBtkhEPxfmgtQX3wDKrlEyB93Sxw1ort08IIYSoDPkErU1Kur8atQRt2VtcGAZAy/gfIYQQotIkAapNbrIFBsgAaCGEEMIcJAGqTZJj1K/lDICGq4sg+soUeCGEEKLSJAGqTQwzwMqfAl8yBshbEiAhhBCi0iQBqk1M6AKTMUBCCCFE5UkCVFvkpkFuivp9o5blVpNB0EIIIUTVSQJUW5S0/rg2BjvncqslZUgXmBBCCFFVkgDVFiUJkGf5A6Cz8ovIKdQB0gIkhBBCVIUkQLXFtbvAl6Nk/I+LvTVOdmWvEySEEEKIm5MEqLaowC7wiRnqHmDS+iOEEEJUjSRAtUUFdoG/mJEHgI+M/xFCCCGqRBKg2qAoH9LPqt9XoAtMWoCEEEKIqpEEqDZIOw2KHuzcwNmr3GoliyBKC5AQQghRNZIA1QYpJVtgBIFGU261kjFAsg+YEEIIUTUWT4DmzJlD06ZNsbe3Jzw8nF27dt2wfnp6OuPHj8fX1xc7OztatWrF6tWrq3ROiyvZAsOz/PE/IF1gQgghhLlYNAFasmQJEydOZNq0aezdu5cOHToQFRXFpUuXyqxfWFhI//79OXPmDMuWLSMmJoavv/4af3//Sp+zVqjAFhhwzSrQ0gUmhBBCVIlFE6CZM2cyduxYxowZQ0hICHPnzsXR0ZH58+eXWX/+/PmkpaWxYsUKunfvTtOmTenduzcdOnSo9DlrhQrsAl+k05Oac2UavCRAQgghRJVYLAEqLCxkz549REZGXg3GyorIyEi2b99e5mtWrlxJREQE48ePx9vbm3bt2vHee++h0+kqfU6L0+shNVb9/gZT4C9lFaAoYKPV0NDRtoaCE0IIIW5NFltOOCUlBZ1Oh7e3t1G5t7c3x48fL/M1p0+fZuPGjYwcOZLVq1cTGxvLM888Q1FREdOmTavUOQEKCgooKCgwPM/MzKzClZko8zwU5YKVDTQILLda4pXuLy8Xe6ysyh8oLYQQQoibs/ggaFPo9Xq8vLz46quvCAsLY9iwYbz++uvMnTu3SuedMWMGbm5uhkdAQICZIq6AkvE/DZuD1qbcakkyBV4IIYQwG4slQB4eHmi1WpKSkozKk5KS8PHxKfM1vr6+tGrVCq1Wayhr06YNiYmJFBYWVuqcAJMnTyYjI8PwOHfuXBWuzESmDoCWGWBCCCFElVksAbK1tSUsLIwNGzYYyvR6PRs2bCAiIqLM13Tv3p3Y2Fj0er2h7MSJE/j6+mJra1upcwLY2dnh6upq9Kgxhl3gKzgFXlqAhBBCiCqzaBfYxIkT+frrr/nuu+84duwY48aNIycnhzFjxgAwatQoJk+ebKg/btw40tLSeP755zlx4gS///477733HuPHj6/wOWudkjWAbjADDK6OAZIWICGEEKLqLDYIGmDYsGEkJyczdepUEhMT6dixI2vWrDEMYo6Pj8fK6mqOFhAQwNq1a3nxxRcJDQ3F39+f559/ntdee63C56x1kq9ZBfoGSrbB8JYWICGEEKLKNIqiKJYOorbJzMzEzc2NjIyM6u0Oy7sM/9dU/X5yAti5lFu11webiE/L5aenIujarGH1xSSEEELUUaZ8ftepWWC3nJQr6/+4+N0w+VEUxdAC5CstQEIIIUSVSQJkSRWcAZaeW0RhsTrw28vVrrqjEkIIIW55kgBZUsrNt8CAq+N/GjrZYmetvWFdIYQQQtycJECWVMFd4A0DoGUGmBBCCGEWkgBZUgW7wK5OgZfuLyGEEMIcJAGylOJCSItTv6/oGkBuDtUdlRBCCFEvSAJkKWmnQdGBrQu4+N6wqmEVaOkCE0IIIcxCEiBLubb7S3Pj3d0TDdtgSBeYEEIIYQ6SAFmKIQG6cfcXXO0Ck0HQQgghhHlIAmQpFRwADde2AEkCJIQQQpiDJECWUsFd4POLdKTnFgHg6yqDoIUQQghzkATIEhSlwrvAlwyAtrexwtXBonvXCiGEELcMSYAsIfMCFGaDRgsNmt2w6tU1gOzR3GSwtBBCCCEqRhIgSyjp/mrYHKxtb1hVVoEWQgghzE8SIEuoYPcXXLsIoiRAQgghhLlIAmQJMgNMCCGEsChJgCyhgrvAg6wCLYQQQlQHSYAsoYK7wIPxIGghhBBCmIckQDUtPxOyLqrfN2p50+pJmQUAeEsXmBBCCGE2kgDVtJLWH2dvcHC/YVW9XjF0gflKAiSEEEKYjSRANc2EPcBScgoo1itYacDTWTZCFUIIIcxFEqCaZkIClJShdn95ONthrZVbJYQQQpiLfKrWNFN2gZcp8EIIIUS1kASoplViDSBZBVoIIYQwL0mAapKuCNJOq99XaAp8HiADoIUQQghzk+3Fa9LlM6AvBhsncPG7afXEK2OApAVICCFAp9NRVFRk6TCEBWm1Wqytrc2yObgkQDUpuWQF6JZgdfPGN1kFWgghVNnZ2SQkJKAoiqVDERbm6OiIr68vtrY33kz8ZiQBqkmG8T837/4CGQQthBCgtvwkJCTg6OiIp6enWf76F3WPoigUFhaSnJxMXFwcQUFBWFWgMaE8kgDVJK82EDoMmvW6adW0nELiUnIACGzkWN2RCSFErVVUVISiKHh6euLg4GDpcIQFOTg4YGNjw9mzZyksLMTevvINBJIA1aTggeqjAv44fBGdXqGdvyuNG0gCJIQQ0vIjgCq1+hidxyxnEWb324ELAAwOvflgaSGEEEKYplYkQHPmzKFp06bY29sTHh7Orl27yq27YMECNBqN0eP6JrDRo0eXqjNgwIDqvgyzScrMZ2dcGgB3hfpaOBohhBCV0adPH1544QVLhyHKYfEusCVLljBx4kTmzp1LeHg4s2bNIioqipiYGLy8vMp8jaurKzExMYbnZTWLDhgwgG+//dbw3M6u7uyl9fvBiygKhAU2kO4vIYQQohpYvAVo5syZjB07ljFjxhASEsLcuXNxdHRk/vz55b5Go9Hg4+NjeHh7e5eqY2dnZ1SnQYMG1XkZZvXbwZLuL2n9EUIIIaqDRROgwsJC9uzZQ2RkpKHMysqKyMhItm/fXu7rsrOzCQwMJCAggCFDhnDkyJFSdTZv3oyXlxfBwcGMGzeO1NTUcs9XUFBAZmam0cNSzqXlsi8+HSsNDJIESAghbhm///47bm5uLFq0iNGjRzN06FDee+89vL29cXd356233qK4uJhXXnmFhg0b0rhxY6OeDIBz587x0EMP4e7uTsOGDRkyZAhnzpwxHN+9ezf9+/fHw8MDNzc3evfuzd69e43OodFo+Oabb7j33ntxdHQkKCiIlStXGo5fvnyZkSNHGmbdBQUFlYrjVmDRBCglJQWdTleqBcfb25vExMQyXxMcHMz8+fP59ddfWbhwIXq9nm7dupGQkGCoM2DAAP73v/+xYcMG/u///o8tW7YwcOBAdDpdmeecMWMGbm5uhkdAQID5LtJEvx+6CMDtzRvh5SLr/wghxPUURSG3sNgij8ouxPjDDz8wYsQIFi1axMiRIwHYuHEjFy5c4K+//mLmzJlMmzaNu+++mwYNGrBz506efvppnnrqKcPnW1FREVFRUbi4uPD333/zzz//4OzszIABAygsLAQgKyuL6Ohotm7dyo4dOwgKCmLQoEFkZWUZxTN9+nQeeughDh48yKBBgxg5ciRpaerY0ylTpnD06FH++OMPjh07xhdffIGHh0dlb1etpVEsuKzmhQsX8Pf3Z9u2bURERBjKX331VbZs2cLOnTtveo6ioiLatGnDiBEjePvtt8usc/r0aVq0aMH69evp169fqeMFBQUUFBQYnmdmZhIQEEBGRgaurq6VuLLKu2v23xy5kMl797bn4fAmNfreQghRG+Xn5xMXF0ezZs2wt7cnt7CYkKlrLRLL0beicLSt2PDZPn360LFjR4KCgnj99df59ddf6d27N6BO1tm8eTOnT582TOtu3bo1Xl5e/PXXX4C6AKSbmxvffPMNw4cPZ+HChbzzzjscO3bMMPa1sLAQd3d3VqxYwZ133lkqBr1ej7u7Oz/88AN33303oLYAvfHGG4bPzJycHJydnfnjjz8YMGAA99xzDx4eHjccimJJ1/8+XCszMxM3N7cKfX5bdBC0h4cHWq2WpKQko/KkpCR8fHwqdA4bGxs6depEbGxsuXWaN2+Oh4cHsbGxZSZAdnZ2tWKQ9KnkbI5cyMTaSsOAdhW7fiGEELXXsmXLuHTpEv/88w+33Xab0bG2bdsarWnj7e1Nu3btDM+1Wi2NGjXi0qVLABw4cIDY2FhcXFyMzpOfn8+pU6cA9fPzjTfeYPPmzVy6dAmdTkdubi7x8fFGrwkNDTV87+TkhKurq+F9xo0bx/3338/evXu58847GTp0KN26dTPDT6N2sWgCZGtrS1hYGBs2bGDo0KGAmq1u2LCBCRMmVOgcOp2OQ4cOMWjQoHLrJCQkkJqaiq9v7R5Ts+qA2v3VI8iDhk5V2+NECCFuVQ42Wo6+FWWx9zZFp06d2Lt3L/Pnz6dLly5Gs5ZtbGyM6mo0mjLL9Ho9oI5/DQsLY9GiRaXex9PTE4Do6GhSU1P55JNPCAwMxM7OjoiICEMX2Y3eu+R9Bg4cyNmzZ1m9ejXr1q2jX79+jB8/nv/+978mXXttZ/Fp8BMnTiQ6OpouXbrQtWtXZs2aRU5ODmPGjAFg1KhR+Pv7M2PGDADeeustbr/9dlq2bEl6ejoffvghZ8+e5YknngDUX5Dp06dz//334+Pjw6lTp3j11Vdp2bIlUVGW+QdTEYqisPLAeUAWPxRCiBvRaDQV7oaytBYtWvDRRx/Rp08ftFotn332WaXP1blzZ5YsWYKXl1e53Tv//PMPn3/+uaFR4Ny5c6SkpJj8Xp6enkRHRxMdHU3Pnj155ZVXJAEyt2HDhpGcnMzUqVNJTEykY8eOrFmzxjAwOj4+3qiJ8PLly4wdO5bExEQaNGhAWFgY27ZtIyQkBFCbDA8ePMh3331Heno6fn5+3Hnnnbz99tu1opurPMcTsziVnIOttRX925ae1i+EEKJuatWqFZs2baJPnz5YW1sza9asSp1n5MiRfPjhhwwZMoS33nqLxo0bc/bsWZYvX86rr75K48aNCQoK4vvvv6dLly5kZmbyyiuvmLx/2tSpUwkLC6Nt27YUFBSwatUq2rRpU6mYazOLJ0AAEyZMKLfLa/PmzUbPP/74Yz7++ONyz+Xg4MDatZYZHFcVJVtf9A32xNXe5ia1hRBC1CXBwcFs3LjR0BJUGY6Ojvz111+89tpr3HfffWRlZeHv70+/fv0MLULz5s3jySefpHPnzgQEBPDee+/x8ssvm/Q+tra2TJ48mTNnzuDg4EDPnj1ZvHhxpWKuzSw6C6y2MmUUuTkoikLvDzcTn5bLZw934m7pAhNCCIMbzfoR9Y+5ZoFZfCVoAQcTMohPy8XRVssdrcve/kMIIYQQ5iMJUC1Q0v3Vr413nRnYJ4QQQtRlkgBZmF6vsOqgOv1d9v4SQgghaoYkQBb279nLJGbm42JvTe9gT0uHI4QQQtQLkgBZWEn3V1RbH+ysKzczQAghhBCmkQTIgop1ev44fKX7q4PM/BJCCCFqiiRAFrTjdBop2YU0dLKlW4tGlg5HCCGEqDckAbKgku6vge18sNHKrRBCCCFqinzqWkhh8dXuL1n4UAghhKhZkgBZyN8nk8nML8bLxY6uzRpaOhwhhBBm1qdPH1544QVLh1GnbN68GY1GQ3p6erW/lyRAFlLS/XVXqC9aK42FoxFCCCHqF0mALCC/SMe6o0mAzP4SQgghLEESIAvYdPwSOYU6/N0d6BTgbulwhBBC1IDff/8dNzc3Fi1axOjRoxk6dCjvvfce3t7euLu789Zbb1FcXMwrr7xCw4YNady4Md9++63ROc6dO8dDDz2Eu7s7DRs2ZMiQIZw5c8ZwfPfu3fTv3x8PDw/c3Nzo3bs3e/fuNTqHRqPhm2++4d5778XR0ZGgoCBWrlxpOH758mVGjhyJp6cnDg4OBAUFlYqjLN26deO1114zKktOTsbGxoa//voLgO+//54uXbrg4uKCj48PDz/8MJcuXTL1R2kWkgBZwG8H1e6vwR380Gik+0sIIUyiKFCYY5mHolQq5B9++IERI0awaNEiRo4cCcDGjRu5cOECf/31FzNnzmTatGncfffdNGjQgJ07d/L000/z1FNPkZCQAEBRURFRUVG4uLjw999/888//+Ds7MyAAQMoLCwEICsri+joaLZu3cqOHTsICgpi0KBBZGVlGcUzffp0HnroIQ4ePMigQYMYOXIkaWlpAEyZMoWjR4/yxx9/cOzYMb744gs8PDxueo0jR45k8eLFKNf8jJYsWYKfnx89e/Y0XMPbb7/NgQMHWLFiBWfOnGH06NGV+plWlUZRKnk3b2GZmZm4ubmRkZGBq6urWc+dXVBM2NvrKCjW8/tzPWjr52bW8wshxK0mPz+fuLg4mjVrhr29vZqIvGeh4QP/uQC2ThWq2qdPHzp27EhQUBCvv/46v/76K7179wZg9OjRbN68mdOnT2NlpbZFtG7dGi8vL0NriU6nw83NjW+++Ybhw4ezcOFC3nnnHY4dO2b447mwsBB3d3dWrFjBnXfeWSoGvV6Pu7s7P/zwA3fffTegtgC98cYbvP322wDk5OTg7OzMH3/8wYABA7jnnnvw8PBg/vz5Jv1okpOT8fPzY+PGjYaEp1u3bvTq1Yv333+/zNf8+++/3HbbbWRlZeHs7MzmzZvp27cvly9fxt3dvczXlPp9uIYpn9/SAlTD1h9NoqBYT3MPJ0J8zZtcCSGEqF2WLVvGiy++yLp16wzJT4m2bdsakh8Ab29v2rdvb3iu1Wpp1KiRoYvowIEDxMbG4uLigrOzM87OzjRs2JD8/HxOnToFQFJSEmPHjiUoKAg3NzdcXV3Jzs4mPj7e6L1DQ0MN3zs5OeHq6mp4n3HjxrF48WI6duzIq6++yrZt2yp0rZ6entx5550sWrQIgLi4OLZv325o8QLYs2cPgwcPpkmTJri4uBh+JtfHVxOsa/wd67mS2V93S/eXEEJUjo2j2hJjqfc2QadOndi7dy/z58+nS5cuRv/v29jYGNXVaDRllun1egCys7MJCwszJBjX8vRUN9OOjo4mNTWVTz75hMDAQOzs7IiIiDB0kd3ovUveZ+DAgZw9e5bVq1ezbt06+vXrx/jx4/nvf/970+sdOXIkzz33HJ9++ik//PAD7du3NyR1OTk5REVFERUVxaJFi/D09CQ+Pp6oqKhS8dUESYBqUHpuIX+dTAZgcKivhaMRQog6SqOpcDeUpbVo0YKPPvqIPn36oNVq+eyzzyp9rs6dO7NkyRK8vLzK7d75559/+Pzzzxk0aBCgDppOSUkx+b08PT2Jjo4mOjqanj178sorr1QoARoyZAhPPvkka9as4YcffmDUqFGGY8ePHyc1NZX333+fgIAAQO0CsxTpAqtBa48kUqRTaO3jQpC3i6XDEUIIUQNatWrFpk2b+Pnnn6u0MOLIkSPx8PBgyJAh/P3338TFxbF582aee+45w0DpoKAgvv/+e44dO8bOnTsZOXIkDg4OJr3P1KlT+fXXX4mNjeXIkSOsWrWKNm3aVOi1Tk5ODB06lClTpnDs2DFGjBhhONakSRNsbW359NNPOX36NCtXrjSMQ7IESYBqUGpOIQ42Wln7Rwgh6png4GA2btzIjz/+yEsvvVSpczg6OvLXX3/RpEkT7rvvPtq0acPjjz9Ofn6+oUVo3rx5XL58mc6dO/Poo4/y3HPP4eXlZdL72NraMnnyZEJDQ+nVqxdarZbFixdX+PUjR47kwIED9OzZkyZNmhjKPT09WbBgAUuXLiUkJIT333+/Qq1K1UVmgZWhOmeB5RYWU6xXcLW3uXllIYQQN5z1I+ofc80CkzFANczRVn7kQgghhKVJF5gQQgghbuq9994zTL+//jFw4EBLh2cyaY4QQgghxE09/fTTPPTQQ2UeM3WgdW0gCZAQQgghbqphw4Y0bNjQ0mGYjXSBCSGEEKLekQRICCFEnSCTlgWY7/dAEiAhhBC1mlarBbDIdgmi9snNzQVKb+dhKhkDJIQQolaztrbG0dGR5ORkbGxsjDYQFfWHoijk5uZy6dIl3N3dDYlxZUkCJIQQolbTaDT4+voSFxfH2bNnLR2OsDB3d3d8fHyqfJ5akQDNmTOHDz/8kMTERDp06MCnn35K165dy6y7YMECxowZY1RmZ2dHfn6+4bmiKEybNo2vv/6a9PR0unfvzhdffEFQUFC1XocQQojqYWtrS1BQkHSD1XM2NjZVbvkpYfEEaMmSJUycOJG5c+cSHh7OrFmziIqKIiYmptz9S1xdXYmJiTE812g0Rsc/+OADZs+ezXfffUezZs2YMmUKUVFRHD16VJZRF0KIOsrKykr+DxdmY/GO1JkzZzJ27FjGjBlDSEgIc+fOxdHRkfnz55f7Go1Gg4+Pj+Hh7e1tOKYoCrNmzeKNN95gyJAhhIaG8r///Y8LFy6wYsWKGrgiIYQQQtR2Fk2ACgsL2bNnD5GRkYYyKysrIiMj2b59e7mvy87OJjAwkICAAIYMGcKRI0cMx+Li4khMTDQ6p5ubG+Hh4eWes6CggMzMTKOHEEIIIW5dFk2AUlJS0Ol0Ri04AN7e3iQmJpb5muDgYObPn8+vv/7KwoUL0ev1dOvWjYSEBADD60w554wZM3BzczM8AgICqnppQgghhKjFLD4GyFQRERFEREQYnnfr1o02bdrw5Zdf8vbbb1fqnJMnT2bixImG5xkZGTRp0kRagoQQQog6pORzuyKLJVo0AfLw8ECr1ZKUlGRUnpSUVOEpbjY2NnTq1InY2FgAw+uSkpLw9fU1OmfHjh3LPIednR12dnaG5yU/QGkJEkIIIeqerKws3NzcbljHogmQra0tYWFhbNiwgaFDhwKg1+vZsGEDEyZMqNA5dDodhw4dYtCgQQA0a9YMHx8fNmzYYEh4MjMz2blzJ+PGjavQOf38/Dh37hwuLi6lZphVVWZmJgEBAZw7dw5XV1eznru2qA/XCHKdtxq5zltHfbhGkOssi6IoZGVl4efnd9PzWrwLbOLEiURHR9OlSxe6du3KrFmzyMnJMaz1M2rUKPz9/ZkxYwYAb731FrfffjstW7YkPT2dDz/8kLNnz/LEE08A6gyxF154gXfeeYegoCDDNHg/Pz9DknUzVlZWNG7cuFqut4Srq+st/QsL9eMaQa7zViPXeeuoD9cIcp3Xu1nLTwmLJ0DDhg0jOTmZqVOnkpiYSMeOHVmzZo1hEHN8fLzRsueXL19m7NixJCYm0qBBA8LCwti2bRshISGGOq+++io5OTk8+eSTpKen06NHD9asWSPrRwghhBACAI0i2+vWqMzMTNzc3MjIyLhlM/b6cI0g13mrkeu8ddSHawS5zqqy+EKI9Y2dnR3Tpk0zGnR9q6kP1whynbcauc5bR324RpDrrCppARJCCCFEvSMtQEIIIYSodyQBEkIIIUS9IwmQEEIIIeodSYCEEEIIUe9IAlSD5syZQ9OmTbG3tyc8PJxdu3ZZOiSzevPNN9FoNEaP1q1bWzqsKvvrr78YPHgwfn5+aDQaVqxYYXRcURSmTp2Kr68vDg4OREZGcvLkScsEWwU3u87Ro0eXur8DBgywTLCVNGPGDG677TZcXFzw8vJi6NChxMTEGNXJz89n/PjxNGrUCGdnZ+6///5S2/XUdhW5zj59+pS6n08//bSFIq6cL774gtDQUMMCeREREfzxxx+G47fCvYSbX+etcC+v9/777xsWNi5h7vspCVANWbJkCRMnTmTatGns3buXDh06EBUVxaVLlywdmlm1bduWixcvGh5bt261dEhVlpOTQ4cOHZgzZ06Zxz/44ANmz57N3Llz2blzJ05OTkRFRZGfn1/DkVbNza4TYMCAAUb398cff6zBCKtuy5YtjB8/nh07drBu3TqKioq48847ycnJMdR58cUX+e2331i6dClbtmzhwoUL3HfffRaM2nQVuU6AsWPHGt3PDz74wEIRV07jxo15//332bNnD//++y933HEHQ4YM4ciRI8CtcS/h5tcJdf9eXmv37t18+eWXhIaGGpWb/X4qokZ07dpVGT9+vOG5TqdT/Pz8lBkzZlgwKvOaNm2a0qFDB0uHUa0A5ZdffjE81+v1io+Pj/Lhhx8aytLT0xU7Ozvlxx9/tECE5nH9dSqKokRHRytDhgyxSDzV5dKlSwqgbNmyRVEU9d7Z2NgoS5cuNdQ5duyYAijbt2+3VJhVdv11Koqi9O7dW3n++ectF1Q1adCggfLNN9/csveyRMl1KsqtdS+zsrKUoKAgZd26dUbXVR33U1qAakBhYSF79uwhMjLSUGZlZUVkZCTbt2+3YGTmd/LkSfz8/GjevDkjR44kPj7e0iFVq7i4OBITE43urZubG+Hh4bfcvQXYvHkzXl5eBAcHM27cOFJTUy0dUpVkZGQA0LBhQwD27NlDUVGR0f1s3bo1TZo0qdP38/rrLLFo0SI8PDxo164dkydPJjc31xLhmYVOp2Px4sXk5OQQERFxy97L66+zxK1yL8ePH89dd91ldN+gev5tWnwvsPogJSUFnU5n2N+shLe3N8ePH7dQVOYXHh7OggULCA4O5uLFi0yfPp2ePXty+PBhXFxcLB1etUhMTAQo896WHLtVDBgwgPvuu49mzZpx6tQp/vOf/zBw4EC2b9+OVqu1dHgm0+v1vPDCC3Tv3p127doB6v20tbXF3d3dqG5dvp9lXSfAww8/TGBgIH5+fhw8eJDXXnuNmJgYli9fbsFoTXfo0CEiIiLIz8/H2dmZX375hZCQEPbv339L3cvyrhNunXu5ePFi9u7dy+7du0sdq45/m5IACbMZOHCg4fvQ0FDCw8MJDAzkp59+4vHHH7dgZMIchg8fbvi+ffv2hIaG0qJFCzZv3ky/fv0sGFnljB8/nsOHD98S49RupLzrfPLJJw3ft2/fHl9fX/r168epU6do0aJFTYdZacHBwezfv5+MjAyWLVtGdHQ0W7ZssXRYZlfedYaEhNwS9/LcuXM8//zzrFu3rsY2LpcusBrg4eGBVqstNVo9KSkJHx8fC0VV/dzd3WnVqhWxsbGWDqXalNy/+nZvAZo3b46Hh0edvL8TJkxg1apVbNq0icaNGxvKfXx8KCwsJD093ah+Xb2f5V1nWcLDwwHq3P20tbWlZcuWhIWFMWPGDDp06MAnn3xyy93L8q6zLHXxXu7Zs4dLly7RuXNnrK2tsba2ZsuWLcyePRtra2u8vb3Nfj8lAaoBtra2hIWFsWHDBkOZXq9nw4YNRn24t5rs7GxOnTqFr6+vpUOpNs2aNcPHx8fo3mZmZrJz585b+t4CJCQkkJqaWqfur6IoTJgwgV9++YWNGzfSrFkzo+NhYWHY2NgY3c+YmBji4+Pr1P282XWWZf/+/QB16n6WRa/XU1BQcMvcy/KUXGdZ6uK97NevH4cOHWL//v2GR5cuXRg5cqThe7Pfz6qP2RYVsXjxYsXOzk5ZsGCBcvToUeXJJ59U3N3dlcTEREuHZjYvvfSSsnnzZiUuLk75559/lMjISMXDw0O5dOmSpUOrkqysLGXfvn3Kvn37FECZOXOmsm/fPuXs2bOKoijK+++/r7i7uyu//vqrcvDgQWXIkCFKs2bNlLy8PAtHbpobXWdWVpby8ssvK9u3b1fi4uKU9evXK507d1aCgoKU/Px8S4deYePGjVPc3NyUzZs3KxcvXjQ8cnNzDXWefvpppUmTJsrGjRuVf//9V4mIiFAiIiIsGLXpbnadsbGxyltvvaX8+++/SlxcnPLrr78qzZs3V3r16mXhyE0zadIkZcuWLUpcXJxy8OBBZdKkSYpGo1H+/PNPRVFujXupKDe+zlvlXpbl+tlt5r6fkgDVoE8//VRp0qSJYmtrq3Tt2lXZsWOHpUMyq2HDhim+vr6Kra2t4u/vrwwbNkyJjY21dFhVtmnTJgUo9YiOjlYURZ0KP2XKFMXb21uxs7NT+vXrp8TExFg26Eq40XXm5uYqd955p+Lp6anY2NgogYGBytixY+tcAl/W9QHKt99+a6iTl5enPPPMM0qDBg0UR0dH5d5771UuXrxouaAr4WbXGR8fr/Tq1Utp2LChYmdnp7Rs2VJ55ZVXlIyMDMsGbqLHHntMCQwMVGxtbRVPT0+lX79+huRHUW6Ne6koN77OW+VeluX6BMjc91OjKIpSubYjIYQQQoi6ScYACSGEEKLekQRICCGEEPWOJEBCCCGEqHckARJCCCFEvSMJkBBCCCHqHUmAhBBCCFHvSAIkhBBCiHpHEiAhhKgAjUbDihUrLB2GEMJMJAESQtR6o0ePRqPRlHoMGDDA0qEJIeooa0sHIIQQFTFgwAC+/fZbozI7OzsLRSOEqOukBUgIUSfY2dnh4+Nj9GjQoAGgdk998cUXDBw4EAcHB5o3b86yZcuMXn/o0CHuuOMOHBwcaNSoEU8++STZ2dlGdebPn0/btm2xs7PD19eXCRMmGB1PSUnh3nvvxdHRkaCgIFauXFm9Fy2EqDaSAAkhbglTpkzh/vvv58CBA4wcOZLhw4dz7NgxAHJycoiKiqJBgwbs3r2bpUuXsn79eqME54svvmD8+PE8+eSTHDp0iJUrV9KyZUuj95g+fToPPfQQBw8eZNCgQYwcOZK0tLQavU4hhJlUebtWIYSoZtHR0YpWq1WcnJyMHu+++66iKOru508//bTRa8LDw5Vx48YpiqIoX331ldKgQQMlOzvbcPz3339XrKysDDva+/n5Ka+//nq5MQDKG2+8YXienZ2tAMoff/xhtusUQtQcGQMkhKgT+vbtyxdffGFU1rBhQ8P3ERERRsciIiLYv38/AMeOHaNDhw44OTkZjnfv3h29Xk9MTAwajYYLFy7Qr1+/G8YQGhpq+N7JyQlXV1cuXbpU2UsSQliQJEBCiDrBycmpVJeUuTg4OFSono2NjdFzjUaDXq+vjpCEENVMxgAJIW4JO3bsKPW8TZs2ALRp04YDBw6Qk5NjOP7PP/9gZWVFcHAwLi4uNG3alA0bNtRozEIIy5EWICFEnVBQUEBiYqJRmbW1NR4eHgAsXbqULl260KNHDxYtWsSuXbuYN28eACNHjmTatGlER0fz5ptvkpyczLPPPsujjz6Kt7c3AG+++SZPP/00Xl5eDBw4kKysLP755x+effbZmr1QIUSNkARICFEnrFmzBl9fX6Oy4OBgjh8/DqgztBYvXswzzzyDr68vP/74IyEhIQA4Ojqydu1ann/+eW677TYcHR25//77mTlzpuFc0dHR5Ofn8/HHH/Pyyy/j4eHBAw88UHMXKISoURpFURRLByGEEFWh0Wj45ZdfGDp0qKVDEULUETIGSAghhBD1jiRAQgghhKh3ZAyQEKLOk558IYSppAVICCGEEPWOJEBCCCGEqHckARJCCCFEvSMJkBBCCCHqHUmAhBBCCFHvSAIkhBBCiHpHEiAhhBBC1DuSAAkhhBCi3pEESAghhBD1zv8D7XmfsJLT/CIAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(history_kmeans['train_auc_1'])\n",
    "plt.plot(history_kmeans['val_auc_1'])\n",
    "\n",
    "plt.title('Model Area Under Curve')\n",
    "plt.ylabel('Area Under Curve')\n",
    "plt.xlabel('Epoch')\n",
    "plt.legend(['kmeans', 'kmeans_val'], loc='lower right')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最终验证集auc在0.855左右，也还不错~"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 压缩算法的压缩效果\n",
    "\n",
    "我们在ImageNet预训练的ResNet网络为例，试一下Int8、Fp8和Kmeans方法对模型参数的压缩效果，看看有什么差异。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.8/site-packages/torchvision/models/_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated since 0.13 and may be removed in the future, please use 'weights' instead.\n",
      "  warnings.warn(\n",
      "/usr/local/lib/python3.8/site-packages/torchvision/models/_utils.py:223: UserWarning: Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and may be removed in the future. The current behavior is equivalent to passing `weights=ResNet50_Weights.IMAGENET1K_V1`. You can also use `weights=ResNet50_Weights.DEFAULT` to get the most up-to-date weights.\n",
      "  warnings.warn(msg)\n"
     ]
    }
   ],
   "source": [
    "from secretflow_fl.utils.compressor import (\n",
    "    QuantizedZeroPoint,\n",
    "    QuantizedFP,\n",
    "    QuantizedKmeans,\n",
    ")\n",
    "from torchvision import models\n",
    "import ssl\n",
    "import time\n",
    "\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "ssl._create_default_https_context = ssl._create_unverified_context\n",
    "net = models.resnet50(pretrained=True)\n",
    "net_params = [p.detach().numpy().flatten() for p in net.parameters()]\n",
    "\n",
    "coms = [\n",
    "    QuantizedZeroPoint(8),\n",
    "    QuantizedFP(8, format='E4M3'),\n",
    "    QuantizedFP(8, format='E5M2'),\n",
    "    QuantizedKmeans(8, n_clusters=100),\n",
    "]\n",
    "losses = []\n",
    "durations = []\n",
    "\n",
    "for c in coms:\n",
    "    start = time.time()\n",
    "    c_params = c.compress(net_params)\n",
    "    dc_params = c.decompress(c_params)\n",
    "    losses.append(sum([np.sum((a - b) ** 2) for a, b in zip(net_params, dc_params)]))\n",
    "    durations.append(time.time() - start)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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WTONHTtW165d03PPPaerV6+mial9+/a6ceOGIiMj1axZM3366afq3bt3mnabNm1S//799cILL2jSpEkqXry4zp8/r6efflobNmxQnz59NGnSJJUqVUo9e/bUxIkTzY+dOXOm3njjDZUrV04TJ07UqFGjVLlyZe3YscPc5tVXX9W0adPUrl07TZ06VYMGDZKTk5MOHjx4z/O6ePFiffjhh3rllVf0/vvv68SJE2rbtq3F+fr+++/1wgsvyM7OTpGRkWrbtq169uyp6Ojoe/Z/N6kXJ3cm9saMGaOuXbuqdOnS+vjjj9WvXz9t3LhRdevWNSeUbt68qdDQUG3fvl19+/bVlClT1Lt3b/31119pkk7S7WF/t27d0tixY+8aT2Zek7Jly2r06NGSpN69e2vhwoVauHCh6tata9FXyZIl5e7uLldXV3Xu3Fnnz5+3qE+9oKtatapFeZUqVWRjY5Pmgg/Aw2/RokWaOnWq+vbtq4EDB2rLli1q3769hg0bpjVr1mjIkCHq3bu3Vq5cqUGDBlk8duHChWrevLlcXFw0btw4DR8+XH/88Ydq1659z8kOExISVKdOHU2ePFlNmjTRpEmT9Oqrr+rQoUM6ffq0pMxfGzzoc7lw4YKaNGmiEydOaOjQoZo8ebI6der0QPNdJScnKywsTP7+/ho/fryKFy+uPn36aN68eWratKmqVq2qcePGydXVVV27dtXx48fv2WdmrkeuXbumhg0basOGDXrjjTf0zjvv6JdffnngW+eOHj2q5557Ts8884wmTJigAgUKqHv37plKOvXs2VP9+vWTv7+/xo0bp6FDh8rR0dHi/L788st699139dRTT+mTTz5RvXr1FBkZme4w96NHj+rFF19Uy5YtFRkZqStXrqhly5ZatGiR+vfvr86dO2vUqFE6duyY2rdvn+aWpOTkZDVt2lQ+Pj4aP368qlSpohEjRmjEiBFpjjV37lxNnjxZvXv31oQJE+Tp6akDBw7o6aef1sGDBzV06FBNmDBBzs7OevbZZ7V8+XLzYzNzPdquXTstX75cPXr00NSpU/XGG2/o6tWrOnXq1D3P69ixY7V8+XINGjRIERER2r59uzp16mTRZtq0aerTp4+KFi2q8ePHq06dOnr22WfNf2P349atWzp9+rQKFChgUf7KK69o8ODBqlWrliZNmqQePXpo0aJFCg0NNV+fZfVvbeTIkTp//rymTZt215gy85rUrVtXb7zxhiTp7bffNl8LlS1b1tzP9evX5ebmJnd3d3l6eio8PFwJCQkWx9qzZ4+cnZ0tHidJ1atXN9fnabk6HgOPnHXr1hn58uUz8uXLZ4SEhBhvvfWWsXbtWuPmzZsW7VJSUox69eoZkgwfHx+jY8eOxpQpU4yTJ0+m6TN1WFR6m4ODwz1j+u+tGRMnTjQkGV988YW57ObNm0ZISIjh4uJixMfHG4ZhGG+++abh5uZ212FPwcHBaYaRZUbqsPc7h2ulno8FCxaYyxITEw1fX1+jXbt2d+3vyJEjho2NjdGmTRsjOTnZoi4lJcUwjNvD2+zt7Y0mTZpYtPnss88MScacOXPSxLJ48WJz2aFDhwxJho2NjbF9+3Zz+dq1a9MMw08dft+qVSuLWF5//XVDkvHbb7+Zy1L7PHDggEXbnj17GoULF7a4TccwDKNDhw6Gu7u7cf36dcMwDKN169Zpbmv4L3d3d4thbenp1q2bERAQYN4/fvy4IckoWLCgxW0A3377rSHJWLlypbmsYsWKRtGiRY2rV6+ay6KiogxJFn1mpF69ekZQUJDxzz//GP/8849x6NAhY/DgwYYki9+vEydOGPny5UtzS9O+ffsMW1tbc/mePXsydVvFncMge/ToYTg6Ohpnz541DCP9WzMy+5rc7daMiRMnGn369DEWLVpkfP3118abb75p2NraGqVLlzbi4uLM7cLDw418+fKlG7eXl5fRoUOHuz43ADnrbrdmZPT/1MvLy4iNjTWXR0REGJKM4OBgIykpyVzesWNHw97e3rhx44ZhGIZx9epVw8PDw+jVq5fFcWJiYgx3d/c05f/17rvvGpKMZcuWpalLfY/M7LXBgz6X5cuX33Ood3rXCHce+87/rd26dTMkGR988IG57MqVK4aTk5NhMpmMJUuWmMtT38dHjBhx12Nl9npkwoQJhiRjxYoV5rJ///3XCAoKynBI+p1Sr++OHz9uLgsICDAkGVu3bjWXXbhwwXBwcDAGDhx41/42bdpkSDLeeOONNHWpr/PevXsNScbLL79sUT9o0CBDkrFp06Y0sfzyyy/mstRrHicnJ4tr1hkzZqR5zqmvzZ23PqakpBjNmzc37O3tzbcopr6ubm5uxoULFyziatSokVGxYkXz709qHzVr1jRKly5tLrvX9eiVK1cMScaHH36YYRvDSHvNnPr7UbZsWYtbRSZNmmRIMvbt22cYxu3fj4IFCxrVqlWz+P2fN2+eISlTt0gHBAQYTZo0MV8L7du3z+jSpYshyeIa7scffzQkGYsWLbJ4/Jo1ayzKM/O3ZhiGRf8NGjQwfH19zdcz6d2akdnX5G63ZgwdOtQYMmSI8eWXXxr/+9//zL8rtWrVsjh/zZs3N0qWLJnm8deuXTMkGUOHDr3rc3vUMSICWfLMM89o27ZtatWqlX777TeNHz9eoaGhKlKkiMWQJZPJpLVr1+r9999XgQIF9L///U/h4eEKCAjQCy+8kO63tlOmTNH69esttsyMFPivH374Qb6+vurYsaO5zM7OTm+88YYSEhK0ZcsWSZKHh4euXbt219ssPDw8dODAAR05ciTLcaTHxcVFnTt3Nu/b29urevXq+uuvv+76uBUrViglJUXvvvuubGws/2xNJpMkacOGDbp586b69etn0aZXr15yc3NLM9TdxcXF4tuBMmXKyMPDQ2XLllWNGjXM5ak/pxdjeHi4xX7qZKU//PCDRXm9evVUrlw5875hGPrmm2/UsmVLGYZhMQomNDRUcXFx5iy/h4eHTp8+ne7tEqk8PDy0Y8eOTN168F8vvPCCRSa+Tp06kv7v+Z49e1b79u1T165dLSZfrFevnipWrJjp4xw6dEheXl7mYYgffvihWrVqZTEEd9myZUpJSVH79u0tzomvr69Kly6tzZs3S/q/yY7Wrl2r69evZ+r4w4YNu+uoiKy8Jnfz5ptvavLkyXrxxRfVrl07TZw4UfPnz9eRI0c0depUc7u7TZ7m6OiYqaGTAB4uzz//vMVkbKnvH507d5atra1F+c2bN3XmzBlJt0coxsbGqmPHjhb/e/Lly6caNWqY//dl5JtvvlFwcLDatGmTpi71PTKz1wYP+lxSR7itWrUqzUjEB/Hyyy+bf/bw8FCZMmXk7Oys9u3bm8tT38fvdU0hZe56ZM2aNSpSpIhatWplLnN0dHzgSQXLlStnfq+Vbg/PL1OmzD3j/uabb2QymdIdbXDn6yxJAwYMsKhPnSDxv9dC5cqVU0hIiHk/9XVu2LChihUrlqY8vRj79OljEUefPn108+bNNLe1tmvXTl5eXub9y5cva9OmTWrfvr2uXr1qMRo4NDRUR44csfi9utv1qJOTk+zt7RUVFZXm9oXM6NGjh8V78n+vhXbt2qVLly6pV69eFr//nTp1SjOa4W7WrVtnvhaqWLGiFi5cqB49eujDDz80t1m6dKnc3d31zDPPWPw/qFKlilxcXMz/D+7nb23kyJGKiYnR9OnT063PymtyN5GRkRo7dqzat2+vDh06aN68eRozZox+/vlni9XK/v3333Qnc01daSyvXwuRiECWVatWTcuWLdOVK1f066+/KiIiQlevXtVzzz1nvt9Nuj1b7DvvvKODBw/q7Nmz+t///qenn35aX331lcU/7VTVq1dX48aNLbYGDRpkOb6TJ0+qdOnSaT6wpw57OnnypCTp9ddf1xNPPKGwsDAVLVpUL730knnuglSjR49WbGysnnjiCVWsWFGDBw/W77//nuWYUhUtWtT8ZpmqQIEC93zTOHbsmGxsbCw+zP9X6vMqU6aMRbm9vb1Klixprr9bLO7u7vL3909TJindGEuXLm2xHxgYKBsbmzTDaP+7Gso///yj2NhYff755+Y3pNStR48ekmSeN2HIkCFycXFR9erVVbp0aYWHh1vcPiNJ48eP1/79++Xv76/q1atr5MiRmboQk2RxoSHJ/Iaa+nxTz1t6q7dkZUWX4sWLa/369Vq7dq2mTp2qIkWK6J9//rFY1vLIkSMyDEOlS5dOc14OHjxoPiclSpTQgAEDNGvWLBUqVEihoaGaMmVKmvkh7lSyZEl16dJFn3/+uc6dO5emPiuvSVa9+OKL8vX1tbgoc3Jy0s2bN9Ntf+PGDTk5Od3XsQDknv/+P019/7jX+0rqh6uGDRum+f+zbt26e/7vOXbsmCpUqHDXNpm9NnjQ51KvXj21a9dOo0aNUqFChdS6dWvNnTs3zfwEWZE6F8J/j5vR+3hmPohm5nrk5MmTCgwMTNPuQVcz+++5Te/Y6Tl27Jj8/Pzk6emZYZuTJ0/KxsYmTYy+vr7y8PDIttc5lY2NjUqWLGlR9sQTT0jSPa+Fjh49KsMwNHz48DS/96nJltTf/Xtdjzo4OGjcuHFavXq1fHx8VLduXY0fP14xMTHpnKW07vdayNbWNktzZdWoUUPr16/XmjVr9NFHH8nDw0NXrlyxSIIcOXJEcXFx8vb2TnNeEhISzOfkfv7W6tatqwYNGmQ4V0RWXpOs6t+/v2xsbNJcC6UXb+p8a3n9WojlO3Hf7O3tVa1aNVWrVk1PPPGEevTooaVLl6abqS5cuLA6dOigdu3aqXz58vrqq680b948i6yqtXl7e2vv3r1au3atVq9erdWrV2vu3Lnq2rWrefKqunXr6tixY/r222+1bt06zZo1S5988ommT59u8e1EZqW3hKGkDCf0y0kZxfIgMf73YiXVf/+Rpt5j2blzZ3Xr1i3dx1SqVEnS7YvEw4cPa9WqVVqzZo2++eYbTZ06Ve+++65GjRol6fZcFXXq1NHy5cu1bt06ffjhhxo3bpyWLVumsLCwu8ZsrdfE2dlZjRs3Nu/XqlVLTz31lN5++219+umnkm6fF5PJpNWrV6cb150jMiZMmKDu3bubfzffeOMNRUZGavv27SpatGi6MbzzzjtauHChxo0bp2effdaiLiuvyf3w9/e3mNCtcOHCSk5O1oULFywmur1586YuXbqUbUuNArCe+31fSf3/s3DhQvn6+qZplxvXCvf7XEwmk77++mtt375dK1eu1Nq1a/XSSy9pwoQJ2r59u1xcXDJ8r0xOTs7WWO4mN69HrHHsjM5xZmPJiRgzuhYaNGiQQkND031M6gf/zFyP9uvXTy1bttSKFSu0du1aDR8+XJGRkdq0aZOefPLJu8Zmrd+HQoUKma+FQkNDFRQUpBYtWmjSpEnmUSwpKSny9vbWokWL0u0jNSmXmb+19IwYMUL169fXjBkz0ky+n5XXJKucnJxUsGDBNNdCmzdvlmEYFr+zqV8Y5fVrIRIRyBapE86l903rnezs7FSpUiUdOXLEPOQ8uwUEBOj3339XSkqKxTcfhw4dMtensre3V8uWLdWyZUulpKTo9ddf14wZMzR8+HDzPxpPT0/16NFDPXr0UEJCgurWrauRI0feVyLifgUGBiolJUV//PGHKleunG6b1Od1+PBhi+z8zZs3dfz4cYsPwdnlyJEjFhn+o0ePKiUl5Z7ZcS8vL7m6uio5OTlTcTk7O+uFF17QCy+8oJs3b6pt27YaM2aMIiIizCMKChcurNdff12vv/66Lly4oKeeekpjxoy5ZyLiXlLPa3qzR6dXllmVKlVS586dNWPGDA0aNEjFihVTYGCgDMNQiRIlzN+o3E3FihVVsWJFDRs2TL/88otq1aql6dOn6/3330+3fWBgoPmYd95+I2XtNcnsBV4qwzB04sQJiwuh1N/jXbt2qVmzZubyXbt2KSUlJcPfcwB5T2BgoKTbXxDcz3tVYGBgpibRzuy1QXZ4+umn9fTTT2vMmDFavHixOnXqpCVLlujll182f9v839tU//ttfW4LCAjQH3/8keZD0oO89z2IwMBArV27VpcvX85wVERAQIBSUlJ05MgRiwkAz58/r9jY2Gx/nVNSUvTXX39ZvGf/+eefknTPa6HUazU7O7tM/d5n5no0MDBQAwcO1MCBA3XkyBFVrlxZEyZM0BdffHEfz+7/3HktdOdo5Vu3bunEiRP3/UVF8+bNVa9ePX3wwQd65ZVX5OzsrMDAQG3YsEG1atXK1IiAu/2tpadevXqqX7++xo0bp3fffdeiLiuvSVavhVJv9bhzdFPlypU1a9YsHTx40GLUc+qE7Hn9WohbM5AlqVm7/0q9Jy/1toAjR46kO0tvbGystm3bpgIFCqQZZphdmjVrppiYGH355Zfmslu3bmny5MlycXFRvXr1JCnNihw2Njbmf6Spw6T+28bFxUWlSpV6oCGW9+PZZ5+VjY2NRo8enWbG5tTXo3HjxrK3t9enn35q8RrNnj1bcXFxat68ebbHlbp8WKrJkydLUqZGIbRr107ffPNNuheP//zzj/nn/74G9vb2KleunAzDUFJSkpKTk9PckuDt7S0/P79seZ38/PxUoUIFLViwwGK24y1btmjfvn0P1Pdbb72lpKQkffzxx5Kktm3bKl++fBo1alSavzPDMMznIj4+Ps1qNBUrVpSNjc09n/OwYcOUlJSUZpm2rLwmzs7OktJeRP+3Xapp06bpn3/+UdOmTc1lDRs2lKenZ5rZq6dNm6b8+fPnyO8rgIdTaGio3Nzc9MEHH6R7r3d6/1fu1K5dO/32228WqwykSv1fmtlrgwd15cqVNP+/Uz9MpP5/DggIUL58+bR161aLdnfOo/MwCA0N1ZkzZyzmALtx44ZmzpyZK/G0a9dOhmGYR0Pe6c7XWZLF6luSzO+zOfHe8tlnn1nE8dlnn8nOzk6NGjW66+O8vb3N38xndMtkqntdj16/fj3N8umBgYFydXXNlmuhqlWrqmDBgpo5c6bF9ceiRYvua06KOw0ZMkSXLl0y/161b99eycnJeu+999K0vXXrlvnaIzN/axlJnSvi888/tyjPymuS0bXQjRs30l1p7r333pNhGBbXQq1bt5adnZ3F375hGJo+fbqKFCmimjVr3vV5POoYEYEs6du3r65fv642bdooKChIN2/e1C+//KIvv/xSxYsXN99L/ttvv+nFF19UWFiY6tSpI09PT505c0bz58/X2bNnNXHixDTDwFavXm3+ZuJONWvWTHP/3d307t1bM2bMUPfu3RUdHa3ixYvr66+/1s8//6yJEyfK1dVV0u2Jny5fvqyGDRuqaNGiOnnypCZPnqzKlSubs+jlypVT/fr1VaVKFXl6emrXrl36+uuv053jIieVKlVK77zzjt577z3VqVNHbdu2lYODg3bu3Ck/Pz9FRkbKy8tLERERGjVqlJo2bapWrVrp8OHDmjp1qqpVq2YxKVV2OX78uFq1aqWmTZtq27Zt+uKLL/Tiiy8qODj4no8dO3asNm/erBo1aqhXr14qV66cLl++rN27d2vDhg3moWtNmjSRr6+vatWqJR8fHx08eFCfffaZmjdvLldXV8XGxqpo0aJ67rnnFBwcLBcXF23YsEE7d+7UhAkTsuV5fvDBB2rdurVq1aqlHj166MqVK/rss89UoUKFNEsxZUW5cuXUrFkzzZo1S8OHD1dgYKDef/99RURE6MSJE3r22Wfl6uqq48ePa/ny5erdu7cGDRqkTZs2qU+fPnr++ef1xBNP6NatW1q4cKE5mXA3qaMiUm8/ulNmX5PAwEB5eHho+vTpcnV1lbOzs2rUqKESJUqYJ6RNXXv9p59+0pIlS1S5cmW98sor5mM5OTnpvffeU3h4uJ5//nmFhobqxx9/1BdffKExY8bc9R5gAHmLm5ubpk2bpi5duuipp55Shw4d5OXlpVOnTun7779XrVq1LD7s/dfgwYP19ddf6/nnn9dLL72kKlWq6PLly/ruu+80ffp0BQcHZ/ra4EHNnz9fU6dOVZs2bRQYGKirV69q5syZcnNzM39Idnd31/PPP6/JkyfLZDIpMDBQq1atuu97z3PKK6+8os8++0wdO3bUm2++qcKFC2vRokXmkYhZ/Ub4QTVo0EBdunTRp59+qiNHjqhp06ZKSUnRjz/+qAYNGqhPnz4KDg5Wt27d9Pnnnys2Nlb16tXTr7/+qvnz5+vZZ5+9r7nH7sbR0VFr1qxRt27dVKNGDa1evVrff/+93n777Ux94TZlyhTVrl1bFStWVK9evVSyZEmdP39e27Zt0+nTp/Xbb79Juvf16J9//qlGjRqpffv2KleunGxtbbV8+XKdP38+3WVLs8re3l4jR45U37591bBhQ7Vv314nTpzQvHnz0p1HJCvCwsJUoUIFffzxxwoPD1e9evX0yiuvKDIyUnv37lWTJk1kZ2enI0eOaOnSpZo0aZKee+65TP2tZaRevXqqV69emklqpcy/JpUrV1a+fPk0btw4xcXFycHBQQ0bNtT169f15JNPqmPHjgoKCpJ0e3LxH374QU2bNlXr1q3NxypatKj69eunDz/8UElJSapWrZpWrFihH3/8UYsWLcrwlpk8I4dX5UAes3r1auOll14ygoKCDBcXF8Pe3t4oVaqU0bdvX+P8+fPmdufPnzfGjh1r1KtXzyhcuLBha2trFChQwGjYsKHx9ddfW/R5t+U7lcESgXf671JEqcfv0aOHUahQIcPe3t6oWLFimn6+/vpro0mTJoa3t7dhb29vFCtWzHjllVeMc+fOmdu8//77RvXq1Q0PDw/DycnJCAoKMsaMGZNmudL/ymi5rPSWofzvMmh3M2fOHOPJJ580HBwcjAIFChj16tUz1q9fb9Hms88+M4KCggw7OzvDx8fHeO2114wrV65YtMkoljuXe7yT/rO0UurynX/88Yfx3HPPGa6urkaBAgWMPn36GP/+++9dH3un8+fPG+Hh4Ya/v79hZ2dn+Pr6Go0aNTI+//xzc5sZM2YYdevWNQoWLGg4ODgYgYGBxuDBg81LQSYmJhqDBw82goODDVdXV8PZ2dkIDg42pk6danGsjJabS2+pK/1n+TPDMIwlS5YYQUFBhoODg1GhQgXju+++M9q1a2cEBQWl+9zulNH5Noz/Wwb0zuN98803Ru3atQ1nZ2fD2dnZCAoKMsLDw43Dhw8bhmEYf/31l/HSSy8ZgYGBhqOjo+Hp6Wk0aNDA2LBhg0XfGb2eR44cMfLly5fuEqCZeU0M4/Yyp+XKlTNsbW0t/k5ffvllo1y5coarq6thZ2dnlCpVyhgyZIh5abz/+vzzz40yZcoY9vb2RmBgoPHJJ5+Yl2EDkHvuZ/nO//4/TW+ZYMNIf8m81PahoaGGu7u74ejoaAQGBhrdu3c3du3adc94L126ZPTp08coUqSIYW9vbxQtWtTo1q2bxXLEmbk2eNDnsnv3bqNjx45GsWLFDAcHB8Pb29to0aJFmufwzz//GO3atTPy589vFChQwHjllVeM/fv3p7t8p7Ozc5rnm9n38Qe9Hvnrr7+M5s2bG05OToaXl5cxcOBA45tvvjEkWSz1nZ6Mlu9M730pvWu59Ny6dcv48MMPjaCgIMPe3t7w8vIywsLCjOjoaHObpKQkY9SoUUaJEiUMOzs7w9/f34iIiLBYjvFusaR33ZLe70Xqa3Ps2DGjSZMmRv78+Q0fHx9jxIgRFsuo3+16wzAM49ixY0bXrl0NX19fw87OzihSpIjRokULi+vle12PXrx40QgPDzeCgoIMZ2dnw93d3ahRo4bx1VdfWRwro+U7//t7nd5SsoZhGJ9++qkREBBgODg4GNWrVzd+/vlno0qVKkbTpk3TfW53yuh8G8b/LQN65/E+//xzo0qVKoaTk5Ph6upqVKxY0XjrrbfMy5Bn9m8to+vQ1Oee3v+izLwmhmEYM2fONEqWLGm+ptq8ebNx5coVo3PnzkapUqWM/PnzGw4ODkb58uWNDz74IN3PD8nJycYHH3xgBAQEGPb29kb58uUtlhnOy0yGkQuz5AF4pI0cOVKjRo3SP//8o0KFCuV2OLmmcuXK8vLyuusSsAAA5CUTJ05U//79dfr0aRUpUiS3w8k13bt319dff/1AIyMfdSkpKfLy8lLbtm1z7ZYdPLqYIwIA7iEpKSnNnAxRUVH67bffVL9+/dwJCgCAHPbfJQ5v3LihGTNmqHTp0o91EuJxdOPGjTRzMixYsECXL1/mWgj3hTkiAOAezpw5o8aNG6tz587y8/PToUOHNH36dPn6+urVV1/N7fAAAMgRbdu2VbFixVS5cmXFxcXpiy++0KFDhzJcWhF51/bt29W/f389//zzKliwoHbv3q3Zs2erQoUKev7553M7PDyCSEQAwD0UKFBAVapU0axZs/TPP//I2dlZzZs319ixY1WwYMHcDg8AgBwRGhqqWbNmadGiRUpOTla5cuW0ZMkSvfDCC7kdGqysePHi8vf316effmpeQrVr164aO3as7O3tczs8PIKYIwIAAAAAAFgNc0QAAAAAAACrIREBAAAAAACsJs/PEZGSkqKzZ8/K1dVVJpMpt8MBAMDqDMPQ1atX5efnJxsbvoPIKVxzAAAed5m95sjziYizZ8/K398/t8MAACDX/f333ypatGhuh5Fncc0BAMBt97rmyPOJCFdXV0m3T4Sbm1suRwMAgPXFx8fL39/f/J6InME1BwDgcZfZa448n4hIHRrp5ubGRQEA4LHG7QI5i2sOAABuu9c1BzeKAgAAAAAAqyERAQAAAAAArIZEBIA8Zdq0aapUqZJ5aHRISIhWr15trr9x44bCw8NVsGBBubi4qF27djp//nyG/SUlJWnIkCGqWLGinJ2d5efnp65du+rs2bMW7caMGaOaNWsqf/788vDwSLevU6dOqXnz5sqfP7+8vb01ePBg3bp1y6LNlClTVLZsWTk5OalMmTJasGDB/Z8MAAAASJK2bt2qli1bys/PTyaTSStWrEjT5uDBg2rVqpXc3d3l7OysatWq6dSpU+b6V155RYGBgXJycpKXl5dat26tQ4cO3fW4JpMp3e3DDz80t7l8+bI6deokNzc3eXh4qGfPnkpISDDXjxw5Mt0+nJ2dH/zE5BISEQDylKJFi2rs2LGKjo7Wrl271LBhQ7Vu3VoHDhyQJPXv318rV67U0qVLtWXLFp09e1Zt27bNsL/r169r9+7dGj58uHbv3q1ly5bp8OHDatWqlUW7mzdv6vnnn9drr72Wbj/Jyclq3ry5bt68qV9++UXz58/XvHnz9O6775rbTJs2TRERERo5cqQOHDigUaNGKTw8XCtXrsyGMwMAAPD4unbtmoKDgzVlypR0648dO6batWsrKChIUVFR+v333zV8+HA5Ojqa21SpUkVz587VwYMHtXbtWhmGoSZNmig5OTnD4547d85imzNnjkwmk9q1a2du06lTJx04cEDr16/XqlWrtHXrVvXu3dtcP2jQoDT9lCtXTs8//3w2nJlcYuRxcXFxhiQjLi4ut0MBkEsKFChgzJo1y4iNjTXs7OyMpUuXmusOHjxoSDK2bduW6f5+/fVXQ5Jx8uTJNHVz58413N3d05T/8MMPho2NjRETE2MumzZtmuHm5mYkJiYahmEYISEhxqBBgyweN2DAAKNWrVqZjg1ID++F1sF5BoBHgyRj+fLlFmUvvPCC0blz5yz189tvvxmSjKNHj2b6Ma1btzYaNmxo3v/jjz8MScbOnTvNZatXrzZMJpNx5syZdPvYu3evIcnYunVrluK1hsy+FzIiAkCelZycrCVLlujatWsKCQlRdHS0kpKS1LhxY3OboKAgFStWTNu2bct0v3FxcTKZTBnegpGebdu2qWLFivLx8TGXhYaGKj4+3jxaIzEx0SLrLklOTk769ddflZSUlOljAQAAIPNSUlL0/fff64knnlBoaKi8vb1Vo0aNdG/fSHXt2jXNnTtXJUqUkL+/f6aOc/78eX3//ffq2bOnuWzbtm3y8PBQ1apVzWWNGzeWjY2NduzYkW4/s2bN0hNPPKE6depk7gk+hEhEAMhz9u3bJxcXFzk4OOjVV1/V8uXLVa5cOcXExMje3j5NAsHHx0cxMTGZ6vvGjRsaMmSIOnbsmKXl+WJiYiySEKnHTa2TbicmZs2apejoaBmGoV27dmnWrFlKSkrSxYsXM30sAAAAZN6FCxeUkJCgsWPHqmnTplq3bp3atGmjtm3basuWLRZtp06dKhcXF7m4uGj16tVav3697O3tM3Wc+fPny9XV1eK24JiYGHl7e1u0s7W1laenZ7rXpzdu3NCiRYsskhmPIhIRAPKcMmXKaO/evdqxY4dee+01devWTX/88ccD95uUlKT27dvLMAxNmzYtGyK1NHz4cIWFhenpp5+WnZ2dWrdurW7dukmSbGz4dw0AAJATUlJSJEmtW7dW//79VblyZQ0dOlQtWrTQ9OnTLdp26tRJe/bs0ZYtW/TEE0+offv2unHjRqaOM2fOHHXq1CnNCNisWL58ua5evWq+RnxUcWULIM+xt7dXqVKlVKVKFUVGRio4OFiTJk2Sr6+vbt68qdjYWIv258+fl6+v7137TE1CnDx5UuvXr8/SaAhJ8vX1TbM6R+p+6rGdnJw0Z84cXb9+XSdOnNCpU6dUvHhxubq6ysvLK0vHAwAAQOYUKlRItra2KleunEV52bJlLVbNkCR3d3eVLl1adevW1ddff61Dhw5p+fLl9zzGjz/+qMOHD+vll1+2KPf19dWFCxcsym7duqXLly+ne306a9YstWjRIs1I20cNiQgAeV5KSooSExNVpUoV2dnZaePGjea6w4cP69SpUwoJCcnw8alJiCNHjmjDhg0qWLBglmMICQnRvn37LN5oUhMa/33Ts7OzU9GiRZUvXz4tWbJELVq0YEQEAABADrG3t1e1atV0+PBhi/I///xTAQEBGT7OMAwZhqHExMR7HmP27NmqUqWKgoODLcpDQkIUGxur6Ohoc9mmTZuUkpKiGjVqWLQ9fvy4Nm/e/MjfliFJtrkdAABkp4iICIWFhalYsWK6evWqFi9erKioKK1du1bu7u7q2bOnBgwYIE9PT7m5ualv374KCQnR008/be4jKChIkZGRatOmjZKSkvTcc89p9+7dWrVqlZKTk83363l6eprvCTx16pQuX76sU6dOKTk5WXv37pUklSpVSi4uLmrSpInKlSunLl26aPz48YqJidGwYcMUHh4uBwcHSbff7H799VfVqFFDV65c0ccff6z9+/dr/vz51j2JAAAAeUxCQoKOHj1q3j9+/Lj27t0rT09PFStWTIMHD9YLL7ygunXrqkGDBlqzZo1WrlypqKgoSdJff/2lL7/8Uk2aNJGXl5dOnz6tsWPHysnJSc2aNTP3e+d1ZKr4+HgtXbpUEyZMSBNX2bJl1bRpU/Xq1UvTp09XUlKS+vTpow4dOsjPz8+i7Zw5c1S4cGGFhYVl89nJBVZYwSNXsZQW8Hh56aWXjICAAMPe3t7w8vIyGjVqZKxbt85c/++//xqvv/66UaBAASN//vxGmzZtjHPnzln0IcmYO3euYRiGcfz4cUNSutvmzZvNj+nWrds925w4ccIICwsznJycjEKFChkDBw40kpKSzPV//PGHUblyZcPJyclwc3MzWrdubRw6dChHzhMeL7wXWgfnGQAeXps3b073Wq1bt27mNrNnzzZKlSplODo6GsHBwcaKFSvMdWfOnDHCwsIMb29vw87OzihatKjx4osvprlWu/M6MtWMGTMMJycnIzY2Nt3YLl26ZHTs2NFwcXEx3NzcjB49ehhXr161aJOcnGwULVrUePvttx/sROSwzL4XmgzDMKyZ+LC2+Ph4ubu7Ky4uLsv3dAMAkBfwXmgdnGcAwOMus++FuXrT8bRp01SpUiW5ubnJzc1NISEhWr16tbn+xo0bCg8PV8GCBeXi4qJ27dqlmewNAAAAAAA8OnJ1joiiRYtq7NixKl26tAzD0Pz589W6dWvt2bNH5cuXV//+/fX9999r6dKlcnd3V58+fdS2bVv9/PPPuRk2gBxkisrtCPImo35uRwAAAHD/kkYNzO0Q8iS7EWnnrbCGXE1EtGzZ0mJ/zJgxmjZtmrZv366iRYtq9uzZWrx4sRo2bChJmjt3rsqWLavt27dbTCwHAAAAAAAeDQ/NenDJyclasmSJrl27ppCQEEVHRyspKUmNGzc2twkKClKxYsW0bdu2DPtJTExUfHy8xQYAAAAAAB4OuZ6I2Ldvn1xcXOTg4KBXX31Vy5cvV7ly5RQTEyN7e3t5eHhYtPfx8TEvnZeeyMhIubu7mzd/f/8cfgYAAAAAACCzcj0RUaZMGe3du1c7duzQa6+9pm7duumPP/647/4iIiIUFxdn3v7+++9sjBYAADxstm7dqpYtW8rPz08mk0krVqxI0+bgwYNq1aqV3N3d5ezsrGrVqunUqVPmeibIBgDAenI9EWFvb69SpUqpSpUqioyMVHBwsCZNmiRfX1/dvHlTsbGxFu3Pnz8vX1/fDPtzcHAwr8KRugEAgLzr2rVrCg4O1pQpU9KtP3bsmGrXrq2goCBFRUXp999/1/Dhw+Xo6Ghu079/f61cuVJLly7Vli1bdPbsWbVt29ZaTwEAgMdKrk5WmZ6UlBQlJiaqSpUqsrOz08aNG9WuXTtJ0uHDh3Xq1CmFhITkcpQAAOBhERYWprCwsAzr33nnHTVr1kzjx483lwUGBpp/jouLY4JsAACsKFdHRERERGjr1q06ceKE9u3bp4iICEVFRalTp05yd3dXz549NWDAAG3evFnR0dHq0aOHQkJCuCAAAACZkpKSou+//15PPPGEQkND5e3trRo1aljcvsEE2QAAWFeuJiIuXLigrl27qkyZMmrUqJF27typtWvX6plnnpEkffLJJ2rRooXatWununXrytfXV8uWLcvNkAEAwCPkwoULSkhI0NixY9W0aVOtW7dObdq0Udu2bbVlyxZJYoJsAACsLFdvzZg9e/Zd6x0dHTVlypQM7/kEAAC4m5SUFElS69at1b9/f0lS5cqV9csvv2j69OmqV6/effcdERGhAQMGmPfj4+NJRgAAkAkP3RwRAAAA2aVQoUKytbVVuXLlLMrLli2rn376SZIsJsi+c1REZibIdnBwyJG4AQDIy3J91QwAAICcYm9vr2rVqunw4cMW5X/++acCAgIkyWKC7FRMkA0AQM5hRAQAAHikJSQk6OjRo+b948ePa+/evfL09FSxYsU0ePBgvfDCC6pbt64aNGigNWvWaOXKlYqKipIkiwmyPT095ebmpr59+zJBNgAAOYREBAAAeKTt2rVLDRo0MO+nztvQrVs3zZs3T23atNH06dMVGRmpN954Q2XKlNE333yj2rVrmx/zySefyMbGRu3atVNiYqJCQ0M1depUqz8XAAAeBybDMIzcDiInxcfHy93dXXFxcXJzc8vtcADcgykqtyPIm4z6uR0BchPvhdbBeQaAnJM0amBuh5An2Y2YkK39Zfa9kDkiAAAAAACA1ZCIAAAAAAAAVkMiAgAAAAAAWA2JCAAAAAAAYDUkIgAAAAAAgNWQiAAAAAAAAFZDIgIAAAAAAFgNiQgAAAAAAGA1JCIAAAAAAIDVkIgAAAAAAABWQyICAAAAAABYDYkIAAAAAABgNSQiAAAAAACA1ZCIAAAAAAAAVkMiAgAAAAAAWA2JCAAAAAAAYDUkIgAAAAAAgNWQiAAAAAAAAFZDIgIAAAAAAFgNiQgAAAAAAGA1JCIAAAAAAIDVkIgAAAAAAABWQyICAAAAAABYDYkIAAAAAABgNSQiAAAAAACA1ZCIAAAAAAAAVkMiAgAAAAAAWA2JCAAAAAAAYDUkIgAAAAAAgNWQiAAAAAAAAFZDIgIAAAAAAFgNiQgAAAAAAGA1JCIAAMAjbevWrWrZsqX8/PxkMpm0YsWKDNu++uqrMplMmjhxokX55cuX1alTJ7m5ucnDw0M9e/ZUQkJCzgYOAMBjikQEAAB4pF27dk3BwcGaMmXKXdstX75c27dvl5+fX5q6Tp066cCBA1q/fr1WrVqlrVu3qnfv3jkVMgAAjzXb3A4AAADgQYSFhSksLOyubc6cOaO+fftq7dq1at68uUXdwYMHtWbNGu3cuVNVq1aVJE2ePFnNmjXTRx99lG7iAgAA3D9GRAAAgDwtJSVFXbp00eDBg1W+fPk09du2bZOHh4c5CSFJjRs3lo2NjXbs2JFhv4mJiYqPj7fYAADAvZGIAAAAedq4ceNka2urN954I936mJgYeXt7W5TZ2trK09NTMTExGfYbGRkpd3d38+bv75+tcQMAkFeRiAAAAHlWdHS0Jk2apHnz5slkMmVr3xEREYqLizNvf//9d7b2DwBAXkUiAgAA5Fk//vijLly4oGLFisnW1la2trY6efKkBg4cqOLFi0uSfH19deHCBYvH3bp1S5cvX5avr2+GfTs4OMjNzc1iAwAA98ZklQAAIM/q0qWLGjdubFEWGhqqLl26qEePHpKkkJAQxcbGKjo6WlWqVJEkbdq0SSkpKapRo4bVYwYAIK8jEQEAAB5pCQkJOnr0qHn/+PHj2rt3rzw9PVWsWDEVLFjQor2dnZ18fX1VpkwZSVLZsmXVtGlT9erVS9OnT1dSUpL69OmjDh06sGIGAAA5gFszAADAI23Xrl168skn9eSTT0qSBgwYoCeffFLvvvtupvtYtGiRgoKC1KhRIzVr1ky1a9fW559/nlMhAwDwWMvVERGRkZFatmyZDh06JCcnJ9WsWVPjxo0zf0MhSfXr19eWLVssHvfKK69o+vTp1g4XAAA8hOrXry/DMDLd/sSJE2nKPD09tXjx4myMCgAAZCRXR0Rs2bJF4eHh2r59u9avX6+kpCQ1adJE165ds2jXq1cvnTt3zryNHz8+lyIGAAAAAAAPIldHRKxZs8Zif968efL29lZ0dLTq1q1rLs+fP/9dZ60GAAAAAACPhodqjoi4uDhJt4dH3mnRokUqVKiQKlSooIiICF2/fj3DPhITExUfH2+xAQAAAACAh8NDs2pGSkqK+vXrp1q1aqlChQrm8hdffFEBAQHy8/PT77//riFDhujw4cNatmxZuv1ERkZq1KhR1gobAAAAAABkwUOTiAgPD9f+/fv1008/WZT37t3b/HPFihVVuHBhNWrUSMeOHVNgYGCafiIiIjRgwADzfnx8vPz9/XMucAAAAAAAkGkPRSKiT58+WrVqlbZu3aqiRYvetW2NGjUkSUePHk03EeHg4CAHB4cciRMAAAAAADyYXJ0jwjAM9enTR8uXL9emTZtUokSJez5m7969kqTChQvncHQ5JzIyUtWqVZOrq6u8vb317LPP6vDhwxZtXnnlFQUGBsrJyUleXl5q3bq1Dh06dM++Dx48qFatWsnd3V3Ozs6qVq2aTp06Za4/duyY2rRpIy8vL7m5ual9+/Y6f/68RR9//vmnWrdurUKFCsnNzU21a9fW5s2b0z3epUuXVLRoUZlMJsXGxmb9ZAAAAAAAHiu5mogIDw/XF198ocWLF8vV1VUxMTGKiYnRv//+K+n2h+b33ntP0dHROnHihL777jt17dpVdevWVaVKlXIz9AeSmWVLq1Sporlz5+rgwYNau3atDMNQkyZNlJycnGG/x44dU+3atRUUFKSoqCj9/vvvGj58uBwdHSVJ165dU5MmTWQymbRp0yb9/PPPunnzplq2bKmUlBRzPy1atNCtW7e0adMmRUdHKzg4WC1atFBMTEyaY/bs2fORfi0AAAAAANZlMgzDyLWDm0zpls+dO1fdu3fX33//rc6dO2v//v26du2a/P391aZNGw0bNkxubm6ZOkZ8fLzc3d0VFxeX6cdY2z///CNvb29t2bLFYtnSO/3+++8KDg7O8JYUSerQoYPs7Oy0cOHCdOvXrVunsLAwXblyxXwu4uLiVKBAAa1bt06NGzfWxYsX5eXlpa1bt6pOnTqSpKtXr8rNzU3r169X48aNzf1NmzZNX375pd599101atRIV65ckYeHxwOcCUAyReV2BHmTUT+3I0BuehTeC/MCzjMA5JykUQNzO4Q8yW7EhGztL7Pvhbl+a0Z6W/fu3SVJ/v7+2rJliy5duqQbN27oyJEjGj9+fJ57c89o2dJU165d09y5c1WiRIkMJ95MSUnR999/ryeeeEKhoaHy9vZWjRo1tGLFCnObxMREmUwmizk0HB0dZWNjY54ktGDBgipTpowWLFiga9eu6datW5oxY4a8vb1VpUoV8+P++OMPjR49WgsWLJCNzUO1CiwAAAAA4CHGJ8hcltGypZI0depUubi4yMXFRatXr9b69etlb2+fbj8XLlxQQkKCxo4dq6ZNm2rdunVq06aN2rZtqy1btkiSnn76aTk7O2vIkCG6fv26rl27pkGDBik5OVnnzp2TdHuUyoYNG7Rnzx65urrK0dFRH3/8sdasWaMCBQpIup3Q6Nixoz788EMVK1YsB88OAAAAACCvIRGRy1KXLV2yZEmauk6dOmnPnj3asmWLnnjiCbVv3143btxIt5/UOR5at26t/v37q3Llyho6dKhatGih6dOnS5K8vLy0dOlSrVy5Ui4uLnJ3d1dsbKyeeuop86gGwzAUHh4ub29v/fjjj/r111/17LPPqmXLluZkRUREhMqWLavOnTvnxCkBAAAAAORhJCJyUeqypZs3b0532VJ3d3eVLl1adevW1ddff61Dhw5p+fLl6fZVqFAh2draqly5chblZcuWtVg1o0mTJjp27JguXLigixcvauHChTpz5oxKliwpSdq0aZNWrVqlJUuWqFatWnrqqac0depUOTk5af78+eY2S5cula2trWxtbdWoUSNzDCNGjMiWcwMAAAAAyJtsczuAx5FhGOrbt6+WL1+uqKioTC1bmjp/RmJiYrr19vb2qlatWpplQP/8808FBASkaV+oUCFJt5MKFy5cUKtWrSRJ169fl6Q08z7Y2NiYR11888035pVNJGnnzp166aWX9OOPP2Y4kSYAAAAAABKJiFwRHh6uxYsX69tvvzUvWyrdHgHh5OSkv/76S19++aWaNGkiLy8vnT59WmPHjpWTk5OaNWtm7icoKEiRkZFq06aNJGnw4MF64YUXVLduXTVo0EBr1qzRypUrFRUVZX7M3LlzVbZsWXl5eWnbtm1688031b9/f5UpU0aSFBISogIFCqhbt25699135eTkpJkzZ+r48eNq3ry5JKVJNly8eFHS7dEXrJoBAAAAALgbEhG5YNq0aZKk+vXrW5SnLlvq6OioH3/8URMnTtSVK1fk4+OjunXr6pdffpG3t7e5/eHDh80rbkhSmzZtNH36dEVGRuqNN95QmTJl9M0336h27doWj4mIiNDly5dVvHhxvfPOO+rfv7+5vlChQlqzZo3eeecdNWzYUElJSSpfvry+/fZbBQcH59AZAQAAAAA8LkyGYRi5HUROYk1v4NFiisrtCPImo35uR4DcxHuhdXCeASDnJI0amNsh5El2IyZka3+ZfS9kskoAAAAAAGA13JpxH/jGNufwrS0AAAAA5G2MiAAAAAAAAFZDIgIAAAAAAFgNiQgAAAAAAGA1JCIAAAAAAIDVkIgAAAAAAABWQyICAAAAAABYDYkIAAAAAABgNSQiAAAAAACA1ZCIAAAAAAAAVkMiAgAAAAAAWA2JCAAAAAAAYDUkIgAAAAAAgNWQiAAAAAAAAFZDIgIAADzStm7dqpYtW8rPz08mk0krVqww1yUlJWnIkCGqWLGinJ2d5efnp65du+rs2bMWfVy+fFmdOnWSm5ubPDw81LNnTyUkJFj5mQAA8HggEQEAAB5p165dU3BwsKZMmZKm7vr169q9e7eGDx+u3bt3a9myZTp8+LBatWpl0a5Tp046cOCA1q9fr1WrVmnr1q3q3bu3tZ4CAACPFdvcDgAAAOBBhIWFKSwsLN06d3d3rV+/3qLss88+U/Xq1XXq1CkVK1ZMBw8e1Jo1a7Rz505VrVpVkjR58mQ1a9ZMH330kfz8/HL8OQAA8DhhRAQAAHisxMXFyWQyycPDQ5K0bds2eXh4mJMQktS4cWPZ2Nhox44dGfaTmJio+Ph4iw0AANwbiQgAAPDYuHHjhoYMGaKOHTvKzc1NkhQTEyNvb2+Ldra2tvL09FRMTEyGfUVGRsrd3d28+fv752jsAADkFSQiAADAYyEpKUnt27eXYRiaNm3aA/cXERGhuLg48/b3339nQ5QAAOR9zBEBAADyvNQkxMmTJ7Vp0ybzaAhJ8vX11YULFyza37p1S5cvX5avr2+GfTo4OMjBwSHHYgYAIK9iRAQAAMjTUpMQR44c0YYNG1SwYEGL+pCQEMXGxio6OtpctmnTJqWkpKhGjRrWDhcAgDyPEREAAOCRlpCQoKNHj5r3jx8/rr1798rT01OFCxfWc889p927d2vVqlVKTk42z/vg6ekpe3t7lS1bVk2bNlWvXr00ffp0JSUlqU+fPurQoQMrZgAAkANIRAAAgEfarl271KBBA/P+gAEDJEndunXTyJEj9d1330mSKleubPG4zZs3q379+pKkRYsWqU+fPmrUqJFsbGzUrl07ffrpp1aJHwCAxw2JCAAA8EirX7++DMPIsP5udak8PT21ePHi7AwLAABkgDkiAAAAAACA1ZCIAAAAAAAAVkMiAgAAAAAAWA2JCAAAAAAAYDUkIgAAAAAAgNWQiAAAAAAAAFZDIgIAAAAAAFhNlhIRSUlJatSokY4cOZJT8QAAAAAAgDwsS4kIOzs7/f777zkVCwAAAAAAyOOyfGtG586dNXv27JyIBQAAAAAA5HG2WX3ArVu3NGfOHG3YsEFVqlSRs7OzRf3HH3+cbcEBAAAAAIC8JcuJiP379+upp56SJP35558WdSaTKXuiAgAAAAAAeVKWExGbN2/OiTgAAAAAAMBj4IGW7zx9+rROnz6dXbEAAAAAAIA8LsuJiJSUFI0ePVru7u4KCAhQQECAPDw89N577yklJSVLfUVGRqpatWpydXWVt7e3nn32WR0+fNiizY0bNxQeHq6CBQvKxcVF7dq10/nz57MaNgAAAAAAeAhkORHxzjvv6LPPPtPYsWO1Z88e7dmzRx988IEmT56s4cOHZ6mvLVu2KDw8XNu3b9f69euVlJSkJk2a6Nq1a+Y2/fv318qVK7V06VJt2bJFZ8+eVdu2bbMaNgAAAAAAeAhkeY6I+fPna9asWWrVqpW5rFKlSipSpIhef/11jRkzJtN9rVmzxmJ/3rx58vb2VnR0tOrWrau4uDjNnj1bixcvVsOGDSVJc+fOVdmyZbV9+3Y9/fTTWQ0fAAAAAADkoiyPiLh8+bKCgoLSlAcFBeny5csPFExcXJwkydPTU5IUHR2tpKQkNW7c2OI4xYoV07Zt29LtIzExUfHx8RYbAAAAAAB4OGQ5EREcHKzPPvssTflnn32m4ODg+w4kJSVF/fr1U61atVShQgVJUkxMjOzt7eXh4WHR1sfHRzExMen2ExkZKXd3d/Pm7+9/3zEBAAAAAIDsleVbM8aPH6/mzZtrw4YNCgkJkSRt27ZNf//9t3744Yf7DiQ8PFz79+/XTz/9dN99SFJERIQGDBhg3o+PjycZAQAAAADAQyLLIyLq1aunP//8U23atFFsbKxiY2PVtm1bHT58WHXq1LmvIPr06aNVq1Zp8+bNKlq0qLnc19dXN2/eVGxsrEX78+fPy9fXN92+HBwc5ObmZrEBAAAAAICHQ5ZGRCQlJalp06aaPn16lialzIhhGOrbt6+WL1+uqKgolShRwqK+SpUqsrOz08aNG9WuXTtJ0uHDh3Xq1CnzaAwAAAAAAPDoyFIiws7OTr///nu2HTw8PFyLFy/Wt99+K1dXV/O8D+7u7nJycpK7u7t69uypAQMGyNPTU25uburbt69CQkJYMQMAAAAAgEdQlm/N6Ny5s2bPnp0tB582bZri4uJUv359FS5c2Lx9+eWX5jaffPKJWrRooXbt2qlu3bry9fXVsmXLsuX4AAAAAADAurI8WeWtW7c0Z84cbdiwQVWqVJGzs7NF/ccff5zpvgzDuGcbR0dHTZkyRVOmTMlqqAAAAAAA4CGT5UTE/v379dRTT0mS/vzzT4s6k8mUPVEBAAAAAIA8KUuJiOTkZI0aNUoVK1ZUgQIFciomAAAAAACQR2Vpjoh8+fKpSZMmaZbTBAAAAAAAyIwsT1ZZoUIF/fXXXzkRCwAAAAAAyOOynIh4//33NWjQIK1atUrnzp1TfHy8xQYAAAAAAJCRLE9W2axZM0lSq1atLCanNAxDJpNJycnJ2RcdAAAAAADIU7KciNi8eXNOxAEAAAAAAB4DWb41o169enfdAAAArGnr1q1q2bKl/Pz8ZDKZtGLFCot6wzD07rvvqnDhwnJyclLjxo115MgRizaXL19Wp06d5ObmJg8PD/Xs2VMJCQlWfBYAADw+Mp2IGD9+vP7991/z/s8//6zExETz/tWrV/X6669nb3QAAAD3cO3aNQUHB2vKlCnp1o8fP16ffvqppk+frh07dsjZ2VmhoaG6ceOGuU2nTp104MABrV+/XqtWrdLWrVvVu3dvaz0FAAAeKybDMIzMNMyXL5/OnTsnb29vSZKbm5v27t2rkiVLSpLOnz8vPz+/h26OiPj4eLm7uysuLk5ubm7Z0qcpKlu6QTqM+rkdAXIbf185g7+tx1tOvBc+rEwmk5YvX65nn31W0u3REH5+fho4cKAGDRokSYqLi5OPj4/mzZunDh066ODBgypXrpx27typqlWrSpLWrFmjZs2a6fTp0/Lz88vUsR+n8wwA1pY0amBuh5An2Y2YkK39Zfa9MNMjIv6br8hk/gIAACDXHD9+XDExMWrcuLG5zN3dXTVq1NC2bdskSdu2bZOHh4c5CSFJjRs3lo2NjXbs2JFh34mJiaweBgDAfcjyHBEAAACPipiYGEmSj4+PRbmPj4+5LiYmxjziM5Wtra08PT3NbdITGRkpd3d38+bv75/N0QMAkDeRiAAAALgPERERiouLM29///13bocEAMAjIUvLd86aNUsuLi6SpFu3bmnevHkqVKiQpNuTVQIAADxMfH19Jd2ey6pw4cLm8vPnz6ty5crmNhcuXLB43K1bt3T58mXz49Pj4OAgBweH7A8aAIA8LtOJiGLFimnmzJnmfV9fXy1cuDBNGwAAgIdFiRIl5Ovrq40bN5oTD/Hx8dqxY4dee+01SVJISIhiY2MVHR2tKlWqSJI2bdqklJQU1ahRI7dCBwAgz8p0IuLEiRM5GAYAAMD9SUhI0NGjR837x48f1969e+Xp6alixYqpX79+ev/991W6dGmVKFFCw4cPl5+fn3lljbJly6pp06bq1auXpk+frqSkJPXp00cdOnTI9IoZAAAg87J0awYAAMDDZteuXWrQoIF5f8CAAZKkbt26ad68eXrrrbd07do19e7dW7Gxsapdu7bWrFkjR0dH82MWLVqkPn36qFGjRrKxsVG7du306aefWv25AADwOCARAQAAHmn169e/67LiJpNJo0eP1ujRozNs4+npqcWLF+dEeAAA4D9YNQMAAAAAAFgNiQgAAAAAAGA1JCIAAAAAAIDV3Fci4tixYxo2bJg6duxoXnd79erVOnDgQLYGBwAAAAAA8pYsJyK2bNmiihUraseOHVq2bJkSEhIkSb/99ptGjBiR7QECAAAAAIC8I8uJiKFDh+r999/X+vXrZW9vby5v2LChtm/fnq3BAQAAAACAvCXLiYh9+/apTZs2acq9vb118eLFbAkKAAAAAADkTVlORHh4eOjcuXNpyvfs2aMiRYpkS1AAAAAAACBvynIiokOHDhoyZIhiYmJkMpmUkpKin3/+WYMGDVLXrl1zIkYAAAAAAJBHZDkR8cEHHygoKEj+/v5KSEhQuXLlVLduXdWsWVPDhg3LiRgBAAAAAEAeYZuVxoZhKCYmRp9++qneffdd7du3TwkJCXryySdVunTpnIoRAAAAAADkEVlORJQqVUoHDhxQ6dKl5e/vn1NxAQCAx8CxY8c0d+5cHTt2TJMmTZK3t7dWr16tYsWKqXz58rkdHgAAyAFZujXDxsZGpUuX1qVLl3IqHgAA8JjYsmWLKlasqB07dmjZsmVKSEiQJP32228aMWJELkcHAABySpbniBg7dqwGDx6s/fv350Q8AADgMTF06FC9//77Wr9+vezt7c3lDRs21Pbt23MxMgAAkJOydGuGJHXt2lXXr19XcHCw7O3t5eTkZFF/+fLlbAsOAADkXfv27dPixYvTlHt7e+vixYu5EBEAALCGLCciJk6cmANhAACAx42Hh4fOnTunEiVKWJTv2bNHRYoUyaWoAABATstyIqJbt245EQcAAHjMdOjQQUOGDNHSpUtlMpmUkpKin3/+WYMGDVLXrl1zOzwAAJBDspyIuNONGzd08+ZNizI3N7cHCggAADwePvjgA4WHh8vf31/JyckqV66ckpOT9eKLL2rYsGG5HR4AAMghWU5EXLt2TUOGDNFXX32V7uoZycnJ2RIYAADI2+zt7TVz5kwNHz5c+/fvV0JCgp588kmVLl06t0MDAAA5KMuJiLfeekubN2/WtGnT1KVLF02ZMkVnzpzRjBkzNHbs2JyIEQAA5GHFihVTsWLFcjsMAABgJVlORKxcuVILFixQ/fr11aNHD9WpU0elSpVSQECAFi1apE6dOuVEnAAAII8xDENff/21Nm/erAsXLiglJcWiftmyZbkUGQAAyEk2WX3A5cuXVbJkSUm354NIXa6zdu3a2rp1a/ZGBwAA8qx+/fqpS5cuOn78uFxcXOTu7m6xAQCAvCnLIyJKliyp48ePq1ixYgoKCtJXX32l6tWra+XKlfLw8MiBEAEAQF60cOFCLVu2TM2aNcvtUAAAgBVleUREjx499Ntvv0mShg4dqilTpsjR0VH9+/fX4MGDsz1AAACQN7m7u5tHWQIAgMdHlkdE9O/f3/xz48aNdejQIUVHR6tUqVKqVKlStgYHAADyrpEjR2rUqFGaM2eOnJyccjscAABgJVlORPxXQECAAgICsiMWAADwGGnfvr3+97//ydvbW8WLF5ednZ1F/e7du3MpMgAAkJOynIgYPXr0Xevffffd+w4GAAA8Prp166bo6Gh17txZPj4+MplMuR0SAACwgiwnIpYvX26xn5SUpOPHj8vW1laBgYEkIgAAQKZ8//33Wrt2rWrXrp3boQAAACvKciJiz549acri4+PVvXt3tWnTJluCAgAAeZ+/v7/c3NxyOwwAAGBlWV41Iz1ubm4aNWqUhg8fnh3dAQCAx8CECRP01ltv6cSJE7kdCgAAsKJsSURIUlxcnOLi4rL0mK1bt6ply5by8/OTyWTSihUrLOq7d+8uk8lksTVt2jS7QgYAALmoc+fO2rx5swIDA+Xq6ipPT0+LDQAA5E1ZvjXj008/tdg3DEPnzp3TwoULFRYWlqW+rl27puDgYL300ktq27Ztum2aNm2quXPnmvcdHByyGjIAAHgITZw4MbdDAAAAuSDLiYhPPvnEYt/GxkZeXl7q1q2bIiIistRXWFjYPZMXDg4O8vX1zWqYAADgIdetWzerHSs5OVkjR47UF198oZiYGPn5+al79+4aNmyYebUOwzA0YsQIzZw5U7GxsapVq5amTZum0qVLWy1OAAAeB1lORBw/fjwn4shQVFSUvL29VaBAATVs2FDvv/++ChYsmGH7xMREJSYmmvfj4+OtESYAAMiE+Ph48wSV93qPzs6JLMeNG6dp06Zp/vz5Kl++vHbt2qUePXrI3d1db7zxhiRp/Pjx+vTTTzV//nyVKFFCw4cPV2hoqP744w85OjpmWywAADzuspyIsKamTZuqbdu2KlGihI4dO6a3335bYWFh2rZtm/Lly5fuYyIjIzVq1CgrRwoAADKjQIECOnfunLy9veXh4WEejXAnwzBkMpmUnJycbcf95Zdf1Lp1azVv3lySVLx4cf3vf//Tr7/+aj7mxIkTNWzYMLVu3VqStGDBAvn4+GjFihXq0KFDtsUCAMDjLsuJiDZt2qR70ZCeZcuWZTmgO935pl+xYkVVqlRJgYGBioqKUqNGjdJ9TEREhAYMGGDej4+Pl7+//wPFAQAAssemTZvME1HOnTtX/v7+ab5cSElJ0alTp7L1uDVr1tTnn3+uP//8U0888YR+++03/fTTT/r4448l3R7xGRMTo8aNG5sf4+7urho1amjbtm3pJiIYhQkAwP3JciLC3d1dy5cvl7u7u6pWrSpJio6OVlxcnJ599tlMJynuR8mSJVWoUCEdPXo0w0SEg4MDE1oCAPCQqlevnvnnl156yTw64k6XLl1S48aNs3UOiaFDhyo+Pl5BQUHKly+fkpOTNWbMGHXq1EmSFBMTI0ny8fGxeJyPj4+57r8YhQkAwP3JciLCx8dH7du31/Tp083fYCQnJ+v111+Xm5ubPvzww2wPMtXp06d16dIlFS5cOMeOAQAArCP1Foz/SkhIyPY5Gb766istWrRIixcvVvny5bV3717169dPfn5+953wYBQmAAD3J8uJiDlz5uinn36yGEaZL18+DRgwQDVr1sxSIiIhIUFHjx417x8/flx79+41rx8+atQotWvXTr6+vjp27JjeeustlSpVSqGhoVkNGwAAPCRSP7ybTCYNHz5c+fPnN9clJydrx44dqly5crYec/DgwRo6dKj5FouKFSvq5MmTioyMVLdu3cwrdJ0/f97iC4/z589nGAujMAEAuD9ZTkTcunVLhw4dUpkyZSzKDx06pJSUlCz1tWvXLjVo0MC8n3ph0q1bN02bNk2///675s+fr9jYWPn5+alJkyZ67733eNMHAOARtmfPHkm3R0Ts27dP9vb25jp7e3sFBwdr0KBB2XrM69evy8bGxqIsX7585muXEiVKyNfXVxs3bjQnHuLj47Vjxw699tpr2RoLAACPuywnInr06KGePXvq2LFjql69uiRpx44dGjt2rHr06JGlvurXry/DMDKsX7t2bVbDAwAAD7nNmzdLun1NMWnSpGxdpjMjLVu21JgxY1SsWDGVL19ee/bs0ccff6yXXnpJ0u3RGf369dP777+v0qVLm5fv9PPz07PPPpvj8QEA8DjJciLio48+kq+vryZMmKBz585JkgoXLqzBgwdr4MCB2R4gAADIm+bOnWu1Y02ePFnDhw/X66+/rgsXLsjPz0+vvPKK3n33XXObt956S9euXVPv3r0VGxur2rVra82aNdk+XwUAAI87k3G3IQn3kLpMlTW+ybhf8fHxcnd3V1xcXLbFaYrKlm6QDqN+bkeA3MbfV87gb+vxlhPvhUiL8wwAOSdpFF965wS7EROytb/MvhfaZFiTCW5ubtqzZ49Wr16tK1euPEhXAAAAAADgMZDpWzPGjRunhIQEvffee5JuTzAVFhamdevWSZK8vb21ceNGlS9fPmciBQAAAAAAj7xMj4j48ssvVaFCBfP+119/ra1bt+rHH3/UxYsXVbVqVY0aNSpHggQAAAAAAHlDphMRx48fV6VKlcz7P/zwg5577jnVqlVLnp6eGjZsmLZt25YjQQIAAAAAgLwh04mIW7duycHBwby/bds21axZ07zv5+enixcvZm90AAAAAAAgT8l0IiIwMFBbt26VJJ06dUp//vmn6tata64/ffq0ChYsmP0RAgAAAACAPCPTk1WGh4erT58++vHHH7V9+3aFhISoXLly5vpNmzbpySefzJEgAQAAAABA3pDpRESvXr2UL18+rVy5UnXr1tWIESMs6s+ePauXXnop2wMEAAAAAAB5R6YTEZL00ksvZZhsmDp1arYEBAAAAAAA8q5MzxEBAAAAAADwoEhEAAAAAAAAqyERAQAAAAAArIZEBAAAAAAAsBoSEQAAAAAAwGqytGqGJN24cUOTJ0/W5s2bdeHCBaWkpFjU7969O9uCAwAAAAAAeUuWExE9e/bUunXr9Nxzz6l69eoymUw5ERcAAAAAAMiDspyIWLVqlX744QfVqlUrJ+IBAAAAAAB5WJbniChSpIhcXV1zIhYAAAAAAJDHZTkRMWHCBA0ZMkQnT57MiXgAAAAAAEAeluVbM6pWraobN26oZMmSyp8/v+zs7CzqL1++nG3BAQAAAACAvCXLiYiOHTvqzJkz+uCDD+Tj48NklQAAAAAAINOynIj45ZdftG3bNgUHB+dEPAAAAAAAIA/L8hwRQUFB+vfff3MiFgAAAAAAkMdlORExduxYDRw4UFFRUbp06ZLi4+MtNgAAAAAAgIxk+daMpk2bSpIaNWpkUW4Yhkwmk5KTk7MnMgAAAAAAkOdkORGxefPmnIgDAAAAAAA8BrKciKhXr15OxAEAAAAAAB4DWU5EbN269a71devWve9gAAAAAABA3pblRET9+vXTlJlMJvPPzBEBAAAAAAAykuVVM65cuWKxXbhwQWvWrFG1atW0bt26nIgRAAAAAADkEVkeEeHu7p6m7JlnnpG9vb0GDBig6OjobAkMAAAAAADkPVkeEZERHx8fHT58OLu6AwAAAAAAeVCWExG///67xfbbb79pzZo1evXVV1W5cuUcCBEAAODBnTlzRp07d1bBggXl5OSkihUrateuXeZ6wzD07rvvqnDhwnJyclLjxo115MiRXIwYAIC8Kcu3ZlSuXFkmk0mGYViUP/3005ozZ062BQYAAJBdrly5olq1aqlBgwZavXq1vLy8dOTIERUoUMDcZvz48fr00081f/58lShRQsOHD1doaKj++OMPOTo65mL0AADkLVlORBw/ftxi38bGRl5eXrxBAwCAh9a4cePk7++vuXPnmstKlChh/tkwDE2cOFHDhg1T69atJUkLFiyQj4+PVqxYoQ4dOlg9ZgAA8qos35oREBBgsfn7+5OEAAAAD7XvvvtOVatW1fPPPy9vb289+eSTmjlzprn++PHjiomJUePGjc1l7u7uqlGjhrZt25Zun4mJiYqPj7fYAADAvWU6EbFt2zatWrXKomzBggUqUaKEvL291bt3byUmJmZ7gAAAAA/qr7/+0rRp01S6dGmtXbtWr732mt544w3Nnz9fkhQTEyPp9uTbd/Lx8THX/VdkZKTc3d3Nm7+/f84+CQAA8ohMJyJGjx6tAwcOmPf37dunnj17qnHjxho6dKhWrlypyMjIHAkSAADgQaSkpOipp57SBx98oCeffFK9e/dWr169NH369PvuMyIiQnFxcebt77//zsaIAQDIuzKdiNi7d68aNWpk3l+yZIlq1KihmTNnasCAAfr000/11Vdf5UiQAAAAD6Jw4cIqV66cRVnZsmV16tQpSZKvr68k6fz58xZtzp8/b677LwcHB7m5uVlsAADg3jKdiLhy5YrFcMUtW7YoLCzMvF+tWjW+CQAAAA+lWrVq6fDhwxZlf/75pwICAiTdnrjS19dXGzduNNfHx8drx44dCgkJsWqsAADkdZlORPj4+JhXzLh586Z2796tp59+2lx/9epV2dnZZX+EAAAAD6h///7avn27PvjgAx09elSLFy/W559/rvDwcEmSyWRSv3799P777+u7777Tvn371LVrV/n5+enZZ5/N3eABAMhjMr18Z7NmzTR06FCNGzdOK1asUP78+VWnTh1z/e+//67AwMAcCRIAAOBBVKtWTcuXL1dERIRGjx6tEiVKaOLEierUqZO5zVtvvaVr166pd+/eio2NVe3atbVmzRpWBwMAIJtlOhHx3nvvqW3btqpXr55cXFw0f/582dvbm+vnzJmjJk2a5EiQAAAAD6pFixZq0aJFhvUmk0mjR4/W6NGjrRgVAACPn0wnIgoVKqStW7cqLi5OLi4uypcvn0X90qVL5eLiku0BAgAAAACAvCPTiYhU7u7u6ZZ7eno+cDAAAAAAACBv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",
      "text/plain": [
       "<Figure size 1280x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(12.8, 4.8))\n",
    "x = [1, 2, 3, 4]\n",
    "x_label = ['Int8', 'Fp8-E4M3', 'Fp8-E5M2', 'Kmeans']\n",
    "\n",
    "plt.subplot(121)\n",
    "p1 = plt.bar(x, losses, color='deepskyblue')\n",
    "plt.bar_label(p1, label_type='edge')\n",
    "plt.xticks(x, x_label)\n",
    "plt.title('SSE loss in compressing ResNet50')\n",
    "plt.ylabel('Sum Square Error')\n",
    "\n",
    "plt.subplot(122)\n",
    "p2 = plt.bar(x, durations, color='salmon')\n",
    "plt.bar_label(p2, label_type='edge')\n",
    "plt.xticks(x, x_label)\n",
    "plt.title('Time comsuming in compressing ResNet50')\n",
    "plt.ylabel('time')\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到，kmeans压缩在控制精度损失方面表现最好，但压缩时间非常长。\n",
    "\n",
    "浮点数(Fp8-M4E3)对ResNet模型参数压缩的效果略优于整型(Int8)压缩，时间消耗是整型压缩的3倍。\n",
    "\n",
    "实际应用压缩算法时，可根据计算资源和压缩精度进行平衡。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 总结\n",
    "\n",
    "本篇示例介绍了通讯压缩算法，并在拆分学习的基础之上使用了SecretFlow提供和自行设计的压缩算法。\n",
    "\n",
    "从实验数据可以看出，将32位数压缩为8位的精度损失不大，而理论通信消耗仅为不作压缩时的1/4，因此在需要频繁传输数据和梯度的拆分学习中，加入通讯压缩不失为一个好的选择。\n",
    "\n",
    "本教程使用明文聚合来做演示，同时没有考虑隐藏层的泄露问题，SecretFlow提供了聚合层AggLayer，通过MPC,TEE,HE，以及DP等方式规避隐层明文传输泄露的问题。如果您感兴趣，可以看相关文档。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
